Trailing whitepace deleted.
[bpt/emacs.git] / lisp / emulation / edt.el
dissimilarity index 88%
index 6b2603c..427a803 100644 (file)
-;;; edt.el --- EDT emulation in Emacs
-
-;; Copyright (C) 1986 Free Software Foundation, Inc.
-
-;; Author: Mike Clarkson <mike@yetti.UUCP>
-;; Maintainer: FSF
-;; Created: 27 Aug 1986
-;; Keywords: emulations
-
-;;  This started from public domain code by Mike Clarkson
-;;  but has been greatly altered.
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; Here's my EDT emulation for GNU Emacs that is based on the EDT emulation
-;; for Gosling's Emacs sent out on the net a couple of years ago by Lynn Olson
-;; at Tektronics.  This emulation was widely distributed as the file edt.ml
-;; in the maclib directory of most Emacs distributions.
-;;      
-;; I will gladly take all criticisms and complaints to heart, and will fix what
-;; bugs I can find.  As this is my first Emacs Lisp hack, you may have to root
-;; out a few nasties hidden in the code.  Please let me know if you find any
-;; (sorry, no rewards :-).  I would also be interested if there are better,
-;; cleaner, faster ways of doing some of the things that I have done.
-;;      
-;; You must understand some design considerations that I had in mind.
-;; The intention was not really to "emulate" EDT, but rather to take advantage
-;; of the years of EDT experience that had accumulated in my right hand,
-;; while at the same time taking advantage of EMACS.
-;;      
-;; Some major differences are:
-;;      
-;; HELP            is describe-key;
-;; GOLD/HELP       is describe-function;
-;; FIND            is isearch-forward/backward;
-;; GOLD/HELP       is occur-menu, which finds all instances of a search string;
-;; ENTER           is other-window;
-;; SUBS            is subprocess-command.  Note that you have to change this
-;;                 to `shell' if you are running Un*x;
-;; PAGE            is next-paragraph, because that's more useful than page.
-;; SPECINS         is copy-to-killring;
-;; GOLD/GOLD       is mark-section-wisely, which is my command to mark the
-;;                 section in a manner consistent with the major-mode.  It
-;;                 uses mark-defun for emacs-lisp, lisp, mark-c-function for C,
-;;                 and mark-paragraph for other modes.
-;;      
-;;      
-;; Some subtle differences are:
-;;      
-;; APPEND          is append-to-buffer.  One doesn't append to the kill ring
-;;                 much and SPECINS is now copy-to-killring;
-;; REPLACE         is replace-regexp;
-;; FILL            is fill-region-wisely, which uses indent-region for C, lisp
-;;                 emacs-lisp, and fill-region for others. It asks if you
-;;                 really want to fill-region in TeX-mode, because I find this
-;;                 to be very dangerous.
-;; CHNGCASE        is case-flip for the character under the cursor only.
-;;                 I felt that case-flip region is unlikely, as usually you
-;;                 upcase-region or downcase region.  Also, unlike EDT it
-;;                 is independent of the direction you are going, as that
-;;                 drives me nuts.
-;;      
-;; I use Emacs definition of what a word is.  This is considerably different
-;; from what EDT thinks a word is.  This is not good for dyed-in-the-wool EDT
-;; fans, but is probably preferable for experienced Emacs users.  My assumption
-;; is that the former are a dying breed now that GNU Emacs has made it to VMS,
-;; but let me know how you feel.  Also, when you undelete a word it leave the
-;; point at the end of the undeleted text, rather than the beginning.  I might
-;; change this as I'm not sure if I like this or not. I'm also not sure if I
-;; want it to set the mark each time you delete a character or word.
-;;      
-;; Backspace does not invoke beginning-of-line, because ^H is the help prefix,
-;; and I felt it should be left as such.  You can change this if you like.
-;;      
-;; The ADVANCE and BACKUP keys do not work as terminators for forward or
-;; backward searches. In Emacs, all search strings are terminated by return.
-;; The searches will however go forward or backward depending on your current
-;; direction.  Also, when you change directions, the mode line will not be
-;; updated immediately, but only when you next execute an emacs function.
-;; Personally, I consider this to be a bug, not a feature.
-;;      
-;; This should also work with VT-2xx's, though I haven't tested it extensively
-;; on those terminals.  It assumes that the CSI-map of vt_200.el has been
-;; defined.
-;;      
-;; There are also a whole bunch of GOLD letter, and GOLD character bindings:
-;; look at edtdoc.el for them, or better still, look at the edt.el lisp code,
-;; because after all, in the true Lisp tradition, the source code is *assumed*
-;; to be self-documenting :-)
-;;      
-;; Mike Clarkson,            ...!allegra \             BITNET:  mike@YUYETTI or
-;; CRESS, York University,   ...!decvax   \                 SYMALG@YUSOL
-;; 4700 Keele Street,        ...!ihnp4     > !utzoo!yetti!mike
-;; North York, Ontario,      ...!linus    /
-;; CANADA M3J 1P3.           ...!watmath /      Phone: +1 (416) 736-2100 x 7767
-;;      
-;; Note that I am not on ARPA, and must gateway any ARPA mail through BITNET or
-;; UUCP.  If you have a UUCP or BITNET address please use it for communication
-;; so that I can reach you directly.  If you have both, the BITNET address
-;; is preferred.
-
-;;; Code:
-
-(require 'keypad)
-
-(defvar edt-last-deleted-lines ""
-  "Last text deleted by an EDT emulation `line-delete' command.")
-(defvar edt-last-deleted-words ""
-  "Last text deleted by an EDT emulation `word-delete' command.")
-(defvar edt-last-deleted-chars ""
-  "Last text deleted by an EDT emulation `character-delete' command.")
-
-(defun delete-current-line (num)
-  "Delete one or specified number of lines after point.
-This includes the newline character at the end of each line.
-They are saved for the EDT `undelete-lines' command."
-  (interactive "p")
-  (let ((beg (point)))
-    (forward-line num)
-    (if (not (eq (preceding-char) ?\n))
-       (insert "\n"))
-    (setq edt-last-deleted-lines
-         (buffer-substring beg (point)))
-    (delete-region beg (point))))
-
-(defun delete-to-eol (num)
-  "Delete text up to end of line.
-With argument, delete up to to Nth line-end past point.
-They are saved for the EDT `undelete-lines' command."
-  (interactive "p")
-  (let ((beg (point)))
-    (forward-char 1)
-    (end-of-line num)
-    (setq edt-last-deleted-lines
-         (buffer-substring beg (point)))
-    (delete-region beg (point))))
-
-(defun delete-current-word (num)
-  "Delete one or specified number of words after point.
-They are saved for the EDT `undelete-words' command."
-  (interactive "p")
-  (let ((beg (point)))
-    (forward-word num)
-    (setq edt-last-deleted-words
-         (buffer-substring beg (point)))
-    (delete-region beg (point))))
-
-(defun edt-delete-previous-word (num)
-  "Delete one or specified number of words before point.
-They are saved for the EDT `undelete-words' command."
-  (interactive "p")
-  (let ((beg (point)))
-    (forward-word (- num))
-    (setq edt-last-deleted-words
-         (buffer-substring (point) beg))
-    (delete-region beg (point))))
-
-(defun delete-current-char (num)
-  "Delete one or specified number of characters after point.
-They are saved for the EDT `undelete-chars' command."
-  (interactive "p")
-  (setq edt-last-deleted-chars
-       (buffer-substring (point) (min (point-max) (+ (point) num))))
-  (delete-region (point) (min (point-max) (+ (point) num))))
-
-(defun delete-previous-char (num)
-  "Delete one or specified number of characters before point.
-They are saved for the EDT `undelete-chars' command."
-  (interactive "p")
-  (setq edt-last-deleted-chars
-       (buffer-substring (max (point-min) (- (point) num)) (point)))
-  (delete-region (max (point-min) (- (point) num)) (point)))
-
-(defun undelete-lines ()
-  "Yank lines deleted by last EDT `line-delete' command."
-  (interactive)
-  (insert edt-last-deleted-lines))
-
-(defun undelete-words ()
-  "Yank words deleted by last EDT `word-delete' command."
-  (interactive)
-  (insert edt-last-deleted-words))
-
-(defun undelete-chars ()
-  "Yank characters deleted by last EDT `character-delete' command."
-  (interactive)
-  (insert edt-last-deleted-chars))
-
-(defun next-end-of-line (num)
-  "Move to end of line; if at end, move to end of next line.
-Accepts a prefix argument for the number of lines to move."
-  (interactive "p")
-  (forward-char)
-  (end-of-line num))
-
-(defun previous-end-of-line (num)
-  "Move EOL upward.
-Accepts a prefix argument for the number of lines to move."
-  (interactive "p")
-  (end-of-line (- 1 num)))
-
-(defun forward-to-word (num)
-  "Move to next word-beginning, or to Nth following word-beginning."
-  (interactive "p")
-  (forward-word (1+ num))
-  (forward-word -1))
-
-(defun backward-to-word (num)
-  "Move back to word-end, or to Nth word-end seen."
-  (interactive "p")
-  (forward-word (- (1+ num)))
-  (forward-word 1))
-
-(defun backward-line (num)
-  "Move point to start of previous line.
-Prefix argument serves as repeat-count."
-  (interactive "p")
-  (forward-line (- num)))
-
-(defun scroll-window-down (num)
-  "Scroll the display down a window-full.
-Accepts a prefix argument for the number of window-fulls to scroll."
-  (interactive "p")
-  (scroll-down (- (* (window-height) num) 2)))
-
-(defun scroll-window-up (num)
-  "Scroll the display up a window-full.
-Accepts a prefix argument for the number of window-fulls to scroll."
-  (interactive "p")
-  (scroll-up (- (* (window-height) num) 2)))
-
-(defun next-paragraph (num)
-  "Move to beginning of the next indented paragraph.
-Accepts a prefix argument for the number of paragraphs."
-  (interactive "p")
-  (while (> num 0)
-    (next-line 1)
-    (forward-paragraph)
-    (previous-line 1)
-    (if (eolp) (next-line 1))
-    (setq num (1- num))))
-
-(defun previous-paragraph (num)
-  "Move to beginning of previous indented paragraph.
-Accepts a prefix argument for the number of paragraphs."
-  (interactive "p")
-  (while (> num 0)
-    (backward-paragraph)
-    (previous-line 1)
-    (if (eolp) (next-line 1))
-    (setq num (1- num))))
-
-(defun move-to-beginning ()
-  "Move cursor to the beginning of buffer, but don't set the mark."
-  (interactive)
-  (goto-char (point-min)))
-
-(defun move-to-end ()
-  "Move cursor to the end of buffer, but don't set the mark."
-  (interactive)
-  (goto-char (point-max)))
-
-(defun goto-percent (perc)
-  "Move point to ARG percentage of the buffer."
-  (interactive "NGoto-percentage: ")
-  (if (or (> perc 100) (< perc 0))
-      (error "Percentage %d out of range 0 < percent < 100" perc)
-    (goto-char (/ (* (point-max) perc) 100))))
-
-(defun update-mode-line ()
-  "Ensure mode-line reflects all changes."
-  (set-buffer-modified-p (buffer-modified-p))
-  (sit-for 0))
-
-(defun advance-direction ()
-  "Set EDT Advance mode so keypad commands move forward."
-  (interactive)
-  (setq edt-direction-string " ADVANCE")
-  (define-key function-keymap "\C-c" 'isearch-forward)  ; PF3
-  (define-key function-keymap "8" 'scroll-window-up) ; "8"
-  (define-key function-keymap "7" 'next-paragraph)   ; "7"
-  (define-key function-keymap "1" 'forward-to-word)  ; "1"
-  (define-key function-keymap "2" 'next-end-of-line) ; "2"
-  (define-key function-keymap "3" 'forward-char)     ; "3"
-  (define-key function-keymap "0" 'forward-line)     ; "0"
-  (update-mode-line))
-
-(defun backup-direction ()
-  "Set EDT Backup mode so keypad commands move backward."
-  (interactive)
-  (setq edt-direction-string " BACKUP")
-  (define-key function-keymap "\C-c" 'isearch-backward) ; PF3
-  (define-key function-keymap "8" 'scroll-window-down) ; "8"
-  (define-key function-keymap "7" 'previous-paragraph) ; "7"
-  (define-key function-keymap "1" 'backward-to-word)    ; "1"
-  (define-key function-keymap "2" 'previous-end-of-line) ; "2"
-  (define-key function-keymap "3" 'backward-char)    ; "3"
-  (define-key function-keymap "0" 'backward-line)    ; "0"
-  (update-mode-line))
-
-(defun edt-beginning-of-window ()
-  "Home cursor to top of window."
-  (interactive)
-  (move-to-window-line 0))
-
-(defun edt-line-to-bottom-of-window ()
-  "Move the current line to the top of the window."
-  (interactive)
-  (recenter -1))
-
-(defun edt-line-to-top-of-window ()
-  "Move the current line to the top of the window."
-  (interactive)
-  (recenter 0))
-
-(defun case-flip-character (num)
-  "Change the case of the character under the cursor.
-Accepts a prefix argument of the number of characters to invert."
-  (interactive "p")
-  (while (> num 0)
-    (funcall (if (<= ?a (following-char))
-                'upcase-region 'downcase-region)
-            (point) (1+ (point)))
-    (forward-char 1)
-    (setq num (1- num))))
-
-(defun indent-or-fill-region ()
-  "Fill region in text modes, indent region in programming language modes."
-  (interactive)
-  (if (string= paragraph-start "^$\\|^\f")
-      (indent-region (point) (mark) nil)
-    (fill-region (point) (mark))))
-
-(defun mark-section-wisely ()
-  "Mark the section in a manner consistent with the major-mode.
-Uses mark-defun for emacs-lisp, lisp,
-mark-c-function for C,
-and mark-paragraph for other modes."
-  (interactive)
-  (cond  ((eq major-mode 'emacs-lisp-mode)
-         (mark-defun))
-        ((eq major-mode 'lisp-mode)
-         (mark-defun))
-        ((eq major-mode 'c-mode)
-         (mark-c-function))
-        (t (mark-paragraph))))
-
-;;; Key Bindings
-;;;###autoload
-(defun edt-emulation-on ()
-  "Emulate DEC's EDT editor.
-Note that many keys are rebound; including nearly all keypad keys.
-Use \\[edt-emulation-off] to undo all rebindings except the keypad keys.
-Note that this function does not work if called directly from the .emacs file.
-Instead, the .emacs file should do \"(setq term-setup-hook 'edt-emulation-on)\"
-Then this function will be called at the time when it will work."
-  (interactive)
-  (advance-direction)
-  (edt-bind-gold-keypad)       ;Must do this *after* $TERM.el is loaded
-  (setq edt-mode-old-c-\\ (lookup-key global-map "\C-\\"))
-  (global-set-key "\C-\\" 'quoted-insert)
-  (setq edt-mode-old-delete (lookup-key global-map "\177"))
-  (global-set-key "\177" 'delete-previous-char)      ;"Delete"
-  (setq edt-mode-old-lisp-delete (lookup-key emacs-lisp-mode-map "\177"))
-  (define-key emacs-lisp-mode-map "\177" 'delete-previous-char) ;"Delete"
-  (define-key lisp-mode-map "\177" 'delete-previous-char) ;"Delete"
-  (setq edt-mode-old-linefeed (lookup-key global-map "\C-j"))
-  (global-set-key "\C-j" 'edt-delete-previous-word)           ;"LineFeed"
-  (define-key esc-map "?" 'apropos))                      ;"<ESC>?"
-
-(defun edt-emulation-off ()
-  "Return from EDT emulation to normal Emacs key bindings.
-The keys redefined by \\[edt-emulation-on] are given their old definitions."
-  (interactive)
-  (setq edt-direction-string nil)
-  (global-set-key "\C-\\" edt-mode-old-c-\\)
-  (global-set-key "\177" edt-mode-old-delete)          ;"Delete"
-  (define-key emacs-lisp-mode-map "\177" edt-mode-old-lisp-delete) ;"Delete"
-  (define-key lisp-mode-map "\177" edt-mode-old-lisp-delete) ;"Delete"
-  (global-set-key "\C-j" edt-mode-old-linefeed))           ;"LineFeed"
-
-(define-key function-keymap "u" 'previous-line)                ;Up arrow
-(define-key function-keymap "d" 'next-line)            ;down arrow
-(define-key function-keymap "l" 'backward-char)                ;right arrow
-(define-key function-keymap "r" 'forward-char)         ;left arrow
-(define-key function-keymap "h" 'edt-beginning-of-window)      ;home
-(define-key function-keymap "\C-b" 'describe-key)      ;PF2
-(define-key function-keymap "\C-d" 'delete-current-line);PF4
-(define-key function-keymap "9" 'append-to-buffer)     ;9 keypad key, etc.
-(define-key function-keymap "-" 'delete-current-word)
-(define-key function-keymap "4" 'advance-direction)
-(define-key function-keymap "5" 'backup-direction)
-(define-key function-keymap "6" 'kill-region)
-(define-key function-keymap "," 'delete-current-char)
-(define-key function-keymap "." 'set-mark-command)
-(define-key function-keymap "e" 'other-window)         ;enter key
-(define-key function-keymap "\C-a" 'GOLD-prefix)       ;PF1 ("gold")
-
-(fset 'GOLD-prefix GOLD-map)
-
-(defvar GOLD-map (make-keymap)
-   "`GOLD-map' maps the function keys on the VT100 keyboard preceeded
-by the PF1 key.  GOLD is the ASCII the 7-bit escape sequence <ESC>OP.")
-
-(defun define-keypad-key (keymap function-keymap-slot definition)
-  (let ((function-key-sequence (function-key-sequence function-keymap-slot)))
-    (if function-key-sequence
-       (define-key keymap function-key-sequence definition))))
-
-;;Bind GOLD/Keyboard keys
-
-(define-key GOLD-map "\C-g"  'keyboard-quit)            ; just for safety
-(define-key GOLD-map "\177" 'delete-window)             ;"Delete"
-(define-key GOLD-map "\C-h" 'delete-other-windows)      ;"BackSpace"
-(define-key GOLD-map "\C-m" 'newline-and-indent)        ;"Return"
-(define-key GOLD-map " " 'undo)                                ;"Spacebar"
-(define-key GOLD-map "%" 'goto-percent)                 ; "%"
-(define-key GOLD-map "=" 'goto-line)                    ; "="
-(define-key GOLD-map "`" 'what-line)                    ; "`"
-(define-key GOLD-map "\C-\\" 'split-window-vertically)  ; "Control-\"
-
-; GOLD letter combinations:
-(define-key GOLD-map "b" 'buffer-menu)                  ; "b"
-(define-key GOLD-map "B" 'buffer-menu)                  ; "B"
-(define-key GOLD-map "d" 'delete-window)                ; "d"
-(define-key GOLD-map "D" 'delete-window)                ; "D"
-(define-key GOLD-map "e" 'compile)                      ; "e"
-(define-key GOLD-map "E" 'compile)                      ; "E"
-(define-key GOLD-map "i" 'insert-file)                  ; "i"
-(define-key GOLD-map "I" 'insert-file)                  ; "I"
-(define-key GOLD-map "l" 'goto-line)                    ; "l"
-(define-key GOLD-map "L" 'goto-line)                    ; "L"
-(define-key GOLD-map "m" 'save-some-buffers)           ; "m"
-(define-key GOLD-map "M" 'save-some-buffers)           ; "m"
-(define-key GOLD-map "n" 'next-error)                           ; "n"
-(define-key GOLD-map "N" 'next-error)                           ; "N"
-(define-key GOLD-map "o" 'switch-to-buffer-other-window)        ; "o"
-(define-key GOLD-map "O" 'switch-to-buffer-other-window)        ; "O"
-(define-key GOLD-map "r" 'revert-file)                          ; "r"
-(define-key GOLD-map "r" 'revert-file)                          ; "R"
-(define-key GOLD-map "s" 'save-buffer)                          ; "s"
-(define-key GOLD-map "S" 'save-buffer)                          ; "S"
-(define-key GOLD-map "v" 'find-file-other-window)               ; "v"
-(define-key GOLD-map "V" 'find-file-other-window)               ; "V"
-(define-key GOLD-map "w" 'write-file)                           ; "w"
-(define-key GOLD-map "w" 'write-file)                           ; "W"
-;(define-key GOLD-map "z" 'shrink-window)                 ; "z"
-;(define-key GOLD-map "Z" 'shrink-window)                 ; "z"
-
-;Bind GOLD/Keypad keys
-(defun edt-bind-gold-keypad ()
-  (define-keypad-key GOLD-map ?u 'edt-line-to-top-of-window) ;"up-arrow"
-  (define-keypad-key GOLD-map ?d 'edt-line-to-bottom-of-window) ;"down-arrow"
-  (define-keypad-key GOLD-map ?l 'backward-sentence) ;"left-arrow"
-  (define-keypad-key GOLD-map ?r 'forward-sentence) ;"right-arrow"
-  (define-keypad-key GOLD-map ?\C-a 'mark-section-wisely) ;Gold     "PF1"
-  (define-keypad-key GOLD-map ?\C-b 'describe-function)        ;Help     "PF2"
-  (define-keypad-key GOLD-map ?\C-c 'occur) ;Find     "PF3"
-  (define-keypad-key GOLD-map ?\C-d 'undelete-lines) ;Und Line "PF4"
-  (define-keypad-key GOLD-map ?0 'open-line) ;Open L   "0"
-  (define-keypad-key GOLD-map ?1 'case-flip-character) ;Chgcase  "1"
-  (define-keypad-key GOLD-map ?2 'delete-to-eol) ;Del EOL  "2"
-  (define-keypad-key GOLD-map ?3 'copy-region-as-kill) ;Copy     "3"
-  (define-keypad-key GOLD-map ?4 'move-to-end) ;Bottom   "4"
-  (define-keypad-key GOLD-map ?5 'move-to-beginning) ;Top      "5"
-  (define-keypad-key GOLD-map ?6 'yank)        ;Paste    "6"
-  (define-keypad-key GOLD-map ?7 'execute-extended-command) ;Command  "7"
-  (define-keypad-key GOLD-map ?8 'indent-or-fill-region) ;Fill     "8"
-  (define-keypad-key GOLD-map ?9 'replace-regexp) ;Replace  "9"
-  (define-keypad-key GOLD-map ?- 'undelete-words) ;UND word "-"
-  (define-keypad-key GOLD-map ?, 'undelete-chars) ;UND Char ","
-  (define-keypad-key GOLD-map ?. 'redraw-display) ;Reset Window "."
-  (define-keypad-key GOLD-map ?e 'shell-command)) ;"ENTER"
-
-;; Make direction of motion show in mode line
-;; while EDT emulation is turned on.
-;; Note that the keypad is always turned on when in Emacs.
-
-(or (assq 'edt-direction-string minor-mode-alist)
-    (setq minor-mode-alist (cons '(edt-direction-string edt-direction-string)
-                                minor-mode-alist)))
-
-;;; edt.el ends here
+;;; edt.el --- enhanced EDT keypad mode emulation for GNU Emacs 19
+
+;; Copyright (C) 1986, 1992, 1993, 1994, 1995, 2000, 2001
+;;   Free Software Foundation, Inc.
+
+;; Author: Kevin Gallagher <kevingal@onramp.net>
+;; Maintainer: Kevin Gallagher <kevingal@onramp.net>
+;; Keywords: emulations
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 2, or (at your
+;; option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+
+\f
+;;; Commentary:
+;;
+
+;; This is Version 4.0 of the EDT Emulation for Emacs 19 and above.
+;; It comes with special functions which replicate nearly all of EDT's
+;; keypad mode behavior.  It sets up default keypad and function key
+;; bindings which closely match those found in EDT.  Support is
+;; provided so that users may reconfigure most keypad and function key
+;; bindings to their own liking.
+
+;; NOTE: Version 4.0 contains several enhancements.  See the
+;; Enhancement section below for the details.
+
+;; Getting Started:
+
+;; To start the EDT Emulation, first start Emacs and then enter
+;;
+;;    M-x edt-emulation-on
+;;
+;; to begin the emulation.  After initialization is complete, the
+;; following message will appear below the status line informing you
+;; that the emulation has been enabled: "Default EDT keymap active".
+
+;; You can have the EDT Emulation start up automatically, each time
+;; you initiate a GNU Emacs session, by adding the following line to
+;; your .emacs file:
+;;
+;;    (add-hook term-setup-hook 'edt-emulation-on)
+
+;; IMPORTANT: Be sure to read the file, edt-user.doc, located in the
+;; Emacs "etc" directory.  It contains very helpful user information.
+
+;; The EDT emulation consists of the following files:
+;;
+;; edt-user.doc     - User Instructions and Sample Customization File
+;; edt.el           - EDT Emulation Functions and Default Configuration
+;; edt-lk201.el     - Built-in support for DEC LK-201 Keyboards
+;; edt-vt100.el     - Built-in support for DEC VT-100 (and above) terminals
+;; edt-pc.el        - Built-in support for PC 101 Keyboards under MS-DOS
+;; edt-mapper.el    - Create an EDT LK-201 Map File for Keyboards Without
+;;                      Built-in Support
+
+;; Enhancements:
+
+;; Version 4.0 contains the following enhancements:
+
+;;  1.  Scroll margins at the top and bottom of the window are now
+;;      supported.  (The design was copied from tpu-extras.el.)  By
+;;      default, this feature is enabled, with the top margin set to
+;;      10% of the window and the bottom margin set to 15% of the
+;;      window.  To change these settings, you can invoke the function
+;;      edt-set-scroll-margins in your .emacs file.  For example, the
+;;      following line
+;;
+;;           (edt-set-scroll-margins "20%" "25%")
+;;
+;;      sets the top margin to 20% of the window and the bottom margin
+;;      to 25% of the window.  To disable this feature, set each
+;;      margin to 0%.  You can also invoke edt-set-scroll-margins
+;;      interactively while EDT Emulation is active to change the
+;;      settings for that session.
+;;
+;;      NOTE: Another way to set the scroll margins is to use the
+;;      Emacs customization feature (not available in Emacs 19) to set
+;;      the following two variables directly:
+;;
+;;           edt-top-scroll-margin and edt-bottom-scroll-margin
+;;
+;;      Enter the Emacs `customize' command.  First select the Editing
+;;      group and then select the Emulations group.  Finally, select
+;;      the Edt group and follow the directions.
+;;
+;;  2.  The SUBS command is now supported and bound to GOLD-Enter by
+;;      default.  (This design was copied from tpu-edt.el.)  Note, in
+;;      earlier versions of EDT Emulation, GOLD-Enter was assigned to
+;;      the Emacs function `query-replace'.  The binding of
+;;      `query-replace' has been moved to GOLD-/.  If you prefer to
+;;      restore `query-replace' to GOLD-Enter, then use an EDT user
+;;      customization file, edt-user.el, to do this.  See edt-user.doc
+;;      for details.
+
+;;  3.  EDT Emulation now also works in XEmacs, including the
+;;      highlighting of selected text.
+
+;;  4.  If you access a workstation using an X Server, observe that
+;;      the initialization file generated by edt-mapper.el will now
+;;      contain the name of the X Server vendor.  This is a
+;;      convenience for those who have access to their Unix account
+;;      from more than one type of X Server.  Since different X
+;;      Servers typically require different EDT emulation
+;;      initialization files, edt-mapper.el will now generate these
+;;      different initialization files and save them with different
+;;      names.  Then, the correct initialization file for the
+;;      particular X server in use is loaded correctly automatically.
+
+;;  5.  Also, edt-mapper.el is now capable of binding an ASCII key
+;;      sequence, providing the ASCII key sequence prefix is already
+;;      known by Emacs to be a prefix.  As a result of providing this
+;;      support, some terminal/keyboard/window system configurations,
+;;      which don't have a complete set of sensible function key
+;;      bindings built into Emacs in `function-key-map', can still be
+;;      configured for use with EDT Emulation.  (Note: In a few rare
+;;      circumstances this does not work properly.  In particular, it
+;;      does not work if a subset of the leading ASCII characters in a
+;;      key sequence are recognized by Emacs as having an existing
+;;      binding.  For example, if the keypad 7 (KP-7) key generates
+;;      the sequence \"<ESC>Ow\" and \"<ESC>O\" is already bound to a
+;;      function, pressing KP-7 when told to do so by edt-mapper.el
+;;      will result in edt-mapper.el incorrectly mapping \"<ESC>O\" to
+;;      KP-7 and \"w\" to KP-8.  If something like this happens to
+;;      you, it is probably a bug in the support for your keyboard
+;;      within Emacs OR a bug in the Unix termcap/terminfo support for
+;;      your terminal OR a bug in the terminal emulation software you
+;;      are using.)
+
+;;  6.  The edt-quit function (bound to GOLD-q by default) has been
+;;      modified to warn the user when file-related buffer
+;;      modifications exist.  It now cautions the user that those
+;;      modifications will be lost if the user quits without saving
+;;      those buffers.
+
+
+;;; History:
+;;
+;;  Version 4.0    2000    Added New Features and Fixed a Few Bugs
+;;
+
+\f
+;;; Code:
+
+;;;  Electric Help functions are used for keypad help displays.  A few
+;;;  picture functions are used in rectangular cut and paste commands.
+
+(require 'ehelp)
+(require 'picture)
+
+;;;;
+;;;; VARIABLES and CONSTANTS
+;;;;
+
+;; For backward compatibility to Emacs 19.
+(or (fboundp 'defgroup)
+    (defmacro defgroup (&rest rest)))
+
+(defgroup edt nil
+  "Emacs emulating EDT."
+  :prefix "edt-"
+  :group 'emulations)
+
+;;;
+;;;  Version Information
+;;;
+(defconst edt-version "4.0" "EDT Emulation version number.")
+
+;;;
+;;;  User Configurable Variables
+;;;
+
+;; For backward compatibility to Emacs 19.
+(or (fboundp 'defcustom)
+    (defmacro defcustom (var value doc &rest ignore)
+      `(defvar ,var ,value ,doc)))
+
+(defcustom edt-keep-current-page-delimiter nil
+  "*Emacs MUST be restarted for a change in value to take effect!
+Non-nil leaves Emacs value of `page-delimiter' unchanged within EDT
+Emulation.  If set to nil (the default), the `page-delimiter' variable
+is set to \"\\f\" when edt-emulation-on is first invoked.  This
+setting replicates EDT's page delimiter behavior.  The original value
+is restored when edt-emulation-off is called."
+  :type 'boolean
+  :group 'edt)
+
+(defcustom edt-use-EDT-control-key-bindings nil
+  "*Emacs MUST be restarted for a change in value to take effect!
+Non-nil causes the control key bindings to be replaced with EDT
+bindings.  If set to nil (the default), EDT control key bindings are
+not used and the current Emacs control key bindings are retained for
+use within the EDT emulation."
+  :type 'boolean
+  :group 'edt)
+
+(defcustom edt-word-entities '(?\t)
+  "*Specifies the list of EDT word entity characters.
+The default list, (\?\\t), contains just the TAB character, which
+emulates EDT.  Characters are specified in the list using their
+decimal ASCII values.  A question mark, followed by the actual
+character, can be used to indicate the numerical value of the
+character, instead of the actual decimal value.  So, ?A means the
+numerical value for the letter A, \?/ means the numerical value for /,
+etc.  Several unprintable and special characters have special
+representations, which you can also use:
+
+            \?\\b  specifies  BS, C-h
+            \?\\t  specifies  TAB, C-i
+            \?\\n  specifies  LFD, C-j
+            \?\\v  specifies  VTAB, C-k
+            \?\\f  specifies  FF, C-l
+            \?\\r  specifies  CR, C-m
+            \?\\e  specifies  ESC, C-[
+            \?\\\\  specifies  \\
+
+In EDT Emulation movement-by-word commands, each character in the list
+will be treated as if it were a separate word."
+  :type '(repeat integer)
+  :group 'edt)
+
+(defcustom edt-top-scroll-margin 10
+  "*Scroll margin at the top of the screen.
+Interpreted as a percent of the current window size with a default
+setting of 10%.  If set to 0, top scroll margin is disabled."
+  :type 'integer
+  :group 'edt)
+
+(defcustom edt-bottom-scroll-margin 15
+  "*Scroll margin at the bottom of the screen.
+Interpreted as a percent of the current window size with a default
+setting of 15%.  If set to 0, bottom scroll margin is disabled."
+  :type 'integer
+  :group 'edt)
+
+;;;
+;;; Internal Variables
+;;;
+
+(defvar edt-last-deleted-lines ""
+  "Last text deleted by the EDT emulation DEL L command.")
+
+(defvar edt-last-deleted-words ""
+  "Last text deleted by the EDT emulation DEL W command.")
+
+(defvar edt-last-deleted-chars ""
+  "Last text deleted by the EDT emulation DEL C command.")
+
+(defvar edt-find-last-text ""
+  "Last text found by the EDT emulation FIND command.")
+
+(defvar edt-match-beginning-mark (make-marker)
+  "Used internally by the EDT emulation SUBS command.")
+
+(defvar edt-match-end-mark (make-marker)
+  "Used internally by the EDT emulation SUBS command.")
+
+(defvar edt-last-replaced-key-definition nil
+  "Key definition replaced with `edt-define-key' or `edt-learn' command.")
+
+(defvar edt-direction-string ""
+  "String indicating current direction of movement.")
+
+(defvar edt-select-mode nil
+  "Non-nil means select mode is active.")
+
+(defvar edt-select-mode-current ""
+  "Text displayed in mode line to indicate the state of EDT select mode.
+When select mode is inactive, it is set to an empty string.")
+
+(defconst edt-select-mode-string " Select"
+  "Used in mode line to indicate select mode is active.")
+
+(defconst edt-forward-string " ADVANCE"
+  "Direction string in mode line to indicate forward movement.")
+
+(defconst edt-backward-string "  BACKUP"
+  "Direction string in mode line to indicate backward movement.")
+
+(defvar edt-default-map-active nil
+  "Non-nil indicates that default EDT emulation key bindings are active.
+nil means user-defined custom bindings are active.")
+
+(defvar edt-user-map-configured nil
+  "Non-nil indicates that user custom EDT key bindings are configured.
+This means that an edt-user.el file was found in the user's `load-path'.")
+
+(defvar edt-term nil
+  "Specifies the terminal type, if applicable.")
+
+;;;
+;;;  Emacs version identifiers - currently referenced by
+;;;
+;;;     o edt-emulation-on      o edt-load-keys
+;;;
+(defconst edt-emacs19-p (not (string-lessp emacs-version "19"))
+  "Non-nil if we are running GNU Emacs or XEmacs version 19, or higher.")
+
+(defconst edt-x-emacs19-p
+  (and edt-emacs19-p (string-match "XEmacs" emacs-version))
+  "Non-nil if we are running XEmacs version 19, or higher.")
+
+(defconst edt-gnu-emacs19-p (and edt-emacs19-p (not edt-x-emacs19-p))
+  "Non-nil if we are running GNU Emacs version 19, or higher.")
+
+(defconst edt-emacs-variant (if edt-gnu-emacs19-p "gnu" "xemacs")
+  "Indicates Emacs variant:  GNU Emacs or XEmacs \(aka Lucid Emacs\).")
+
+(defconst edt-window-system (if edt-gnu-emacs19-p window-system (console-type))
+  "Indicates window system \(in GNU Emacs\) or console type \(in XEmacs\).")
+
+(defconst edt-xserver (if (eq edt-window-system 'x)
+                         (if edt-x-emacs19-p
+                             (replace-in-string (x-server-vendor) "[ _]" "-")
+                           (subst-char-in-string ?  ?- (x-server-vendor)))
+                       nil)
+  "Indicates X server vendor name, if applicable.")
+
+(defvar edt-keys-file nil
+  "User's custom keypad and function keys mappings to emulate LK-201 keyboard.")
+\f
+;;;;
+;;;; EDT Emulation Commands
+;;;;
+
+;;; Almost all of EDT's keypad mode commands have equivalent Emacs
+;;; function counterparts.  But many of these counterparts behave
+;;; somewhat differently in Emacs.
+;;;
+;;; So, the following Emacs functions emulate, where practical, the
+;;; exact behavior of the corresponding EDT keypad mode commands.  In
+;;; a few cases, the emulation is not exact, but it should be close
+;;; enough for most EDT die-hards.
+;;;
+
+;;;
+;;; PAGE
+;;;
+;;; Emacs uses the regexp assigned to page-delimiter to determine what
+;;; marks a page break.  This is normally "^\f", which causes the
+;;; edt-page command to ignore form feeds not located at the beginning
+;;; of a line.  To emulate the EDT PAGE command exactly,
+;;; page-delimiter is set to "\f" when EDT emulation is turned on, and
+;;; restored to its original value when EDT emulation is turned off.
+;;; But this can be overridden if the EDT definition is not desired by
+;;; placing
+;;;
+;;;         (setq edt-keep-current-page-delimiter t)
+;;;
+;;; in your .emacs file.
+
+(defun edt-page-forward (num)
+  "Move forward to just after next page delimiter.
+Argument NUM is the number of page delimiters to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (if (eobp)
+      (error "End of buffer")
+       (progn
+         (forward-page num)
+         (if (eobp)
+                 (edt-line-to-bottom-of-window)
+               (edt-line-to-top-of-window)))))
+
+(defun edt-page-backward (num)
+  "Move backward to just after previous page delimiter.
+Argument NUM is the number of page delimiters to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (if (bobp)
+      (error "Beginning of buffer")
+       (progn
+         (backward-page num)
+      (edt-line-to-top-of-window)
+         (if edt-x-emacs19-p (setq zmacs-region-stays t)))))
+
+(defun edt-page (num)
+  "Move in current direction to next page delimiter.
+Argument NUM is the number of page delimiters to move."
+  (interactive "p")
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-page-forward num)
+    (edt-page-backward num)))
+
+;;;
+;;; SECT
+;;;
+;;; EDT defaults a section size to be 16 lines of its one and only
+;;; 24-line window.  That's two-thirds of the window at a time.  The
+;;; EDT SECT commands moves the cursor, not the window.
+;;;
+;;; This emulation of EDT's SECT moves the cursor approximately
+;;; two-thirds of the current window at a time.
+
+(defun edt-sect-forward (num)
+  "Move cursor forward two-thirds of a window's number of lines.
+Argument NUM is the number of sections to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (edt-line-forward (* (* (/ (- (window-height) 1) 3) 2) num)))
+
+
+(defun edt-sect-backward (num)
+  "Move cursor backward two-thirds of a window.
+Argument NUM is the number of sections to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (edt-line-backward (* (* (/ (- (window-height) 1) 3) 2) num)))
+
+(defun edt-sect (num)
+  "Move in current direction a full window.
+Argument NUM is the number of sections to move."
+  (interactive "p")
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-sect-forward num)
+    (edt-sect-backward num)))
+
+;;;
+;;; BEGINNING OF LINE
+;;;
+;;; EDT's beginning-of-line command is not affected by current
+;;; direction, for some unknown reason.
+
+(defun edt-beginning-of-line (num)
+  "Move backward to next beginning of line mark.
+Argument NUM is the number of BOL marks to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (let ((beg (edt-current-line)))
+    (if (bolp)
+       (forward-line (* -1 num))
+      (progn
+       (setq num (1- num))
+       (forward-line (* -1 num))))
+    (edt-top-check beg num))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+
+;;;
+;;; EOL (End of Line)
+;;;
+
+(defun edt-end-of-line-forward (num)
+  "Move forward to next end of line mark.
+Argument NUM is the number of EOL marks to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (let ((beg (edt-current-line)))
+    (forward-char)
+    (end-of-line num)
+    (edt-bottom-check beg num))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+
+(defun edt-end-of-line-backward (num)
+  "Move backward to next end of line mark.
+Argument NUM is the number of EOL marks to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (let ((beg (edt-current-line)))
+    (end-of-line (1- num))
+    (edt-top-check beg num))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+
+(defun edt-end-of-line (num)
+  "Move in current direction to next end of line mark.
+Argument NUM is the number of EOL marks to move."
+  (interactive "p")
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-end-of-line-forward num)
+    (edt-end-of-line-backward num)))
+
+;;;
+;;; WORD
+;;;
+;;; This one is a tad messy.  To emulate EDT's behavior everywhere in
+;;; the file (beginning of file, end of file, beginning of line, end
+;;; of line, etc.) it takes a bit of special handling.
+;;;
+;;; The variable edt-word-entities contains a list of characters which
+;;; are to be viewed as distinct words where ever they appear in the
+;;; buffer.  This emulates the EDT line mode command SET ENTITY WORD.
+
+
+(defun edt-one-word-forward ()
+  "Move forward to first character of next word."
+  (interactive)
+  (if (eobp)
+      (error "End of buffer"))
+  (if (eolp)
+      (forward-char)
+    (progn
+      (if (memq (following-char) edt-word-entities)
+         (forward-char)
+       (while (and
+               (not (eolp))
+               (not (eobp))
+               (not (eq ?\  (char-syntax (following-char))))
+               (not (memq (following-char) edt-word-entities)))
+         (forward-char)))
+      (while (and
+             (not (eolp))
+             (not (eobp))
+             (eq ?\  (char-syntax (following-char)))
+             (not (memq (following-char) edt-word-entities)))
+       (forward-char))))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-one-word-backward ()
+  "Move backward to first character of previous word."
+  (interactive)
+  (if (bobp)
+      (error "Beginning of buffer"))
+  (if (bolp)
+      (backward-char)
+    (progn
+      (backward-char)
+      (while (and
+             (not (bolp))
+             (not (bobp))
+             (eq ?\  (char-syntax (following-char)))
+             (not (memq (following-char) edt-word-entities)))
+       (backward-char))
+      (if (not (memq (following-char) edt-word-entities))
+         (while (and
+                 (not (bolp))
+                 (not (bobp))
+                 (not (eq ?\  (char-syntax (preceding-char))))
+                 (not (memq (preceding-char) edt-word-entities)))
+           (backward-char)))))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-word-forward (num)
+  "Move forward to first character of next word.
+Argument NUM is the number of words to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (while (> num 0)
+    (edt-one-word-forward)
+    (setq num (1- num))))
+
+(defun edt-word-backward (num)
+  "Move backward to first character of previous word.
+Argument NUM is the number of words to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (while (> num 0)
+    (edt-one-word-backward)
+    (setq num (1- num))))
+
+(defun edt-word (num)
+  "Move in current direction to first character of next word.
+Argument NUM is the number of words to move."
+  (interactive "p")
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-word-forward num)
+    (edt-word-backward num)))
+
+;;;
+;;; CHAR
+;;;
+
+(defun edt-character (num)
+  "Move in current direction to next character.
+Argument NUM is the number of characters to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (if (equal edt-direction-string edt-forward-string)
+      (forward-char num)
+    (backward-char num))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+;;;
+;;; LINE
+;;;
+;;; When direction is set to BACKUP, LINE behaves just like BEGINNING
+;;; OF LINE in EDT.  So edt-line-backward is not really needed as a
+;;; separate function.
+
+(defun edt-line-backward (num)
+  "Move backward to next beginning of line mark.
+Argument NUM is the number of BOL marks to move."
+  (interactive "p")
+  (edt-beginning-of-line num))
+
+(defun edt-line-forward (num)
+  "Move forward to next beginning of line mark.
+Argument NUM is the number of BOL marks to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (let ((beg (edt-current-line)))
+    (forward-line num)
+    (edt-bottom-check beg num))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-line (num)
+  "Move in current direction to next beginning of line mark.
+Argument NUM is the number of BOL marks to move."
+  (interactive "p")
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-line-forward num)
+    (edt-line-backward num)))
+
+;;;
+;;; UP and DOWN Arrows
+;;;
+
+(defun edt-next-line (num)
+  "Move cursor down one line.
+Argument NUM is the number of lines to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (let ((beg (edt-current-line)))
+    (next-line num)
+    (edt-bottom-check beg num))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-previous-line (num)
+  "Move cursor up one line.
+Argument NUM is the number of lines to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (let ((beg (edt-current-line)))
+    (previous-line num)
+    (edt-top-check beg num))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+
+;;;
+;;; TOP
+;;;
+
+(defun edt-top ()
+  "Move cursor to the beginning of buffer."
+  (interactive)
+  (goto-char (point-min))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+;;;
+;;; BOTTOM
+;;;
+
+(defun edt-bottom ()
+  "Move cursor to the end of buffer."
+  (interactive)
+  (goto-char (point-max))
+  (edt-line-to-bottom-of-window))
+
+;;;
+;;; FIND
+;;;
+
+(defun edt-find-forward (&optional find)
+  "Find first occurrence of a string in forward direction and save it.
+Optional argument FIND is t is this function is called from `edt-find'."
+  (interactive)
+  (if (not find)
+      (set 'edt-find-last-text (read-string "Search forward: ")))
+  (let* ((left nil)
+        (beg (edt-current-line))
+        (height (window-height))
+        (top-percent
+         (if (= 0 edt-top-scroll-margin) 10 edt-top-scroll-margin))
+        (bottom-percent
+         (if (= 0 edt-bottom-scroll-margin) 15 edt-bottom-scroll-margin))
+        (top-margin (/ (* height top-percent) 100))
+        (bottom-up-margin (+ 1 (/ (* height bottom-percent) 100)))
+        (bottom-margin (max beg (- height bottom-up-margin 1)))
+        (top (save-excursion (move-to-window-line top-margin) (point)))
+        (bottom (save-excursion (move-to-window-line bottom-margin) (point)))
+        (far (save-excursion
+               (goto-char bottom) (forward-line (- height 2)) (point))))
+    (if (search-forward edt-find-last-text)
+       (progn
+         (search-backward edt-find-last-text)
+         (edt-set-match)
+         (cond((> (point) far)
+               (setq left (save-excursion (forward-line height)))
+               (if (= 0 left) (recenter top-margin)
+                 (recenter (- left bottom-up-margin))))
+              (t
+               (and (> (point) bottom) (recenter bottom-margin)))))))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-find-backward (&optional find)
+  "Find first occurrence of a string in the backward direction and save it.
+Optional argument FIND is t if this function is called from `edt-find'."
+  (interactive)
+  (if (not find)
+      (set 'edt-find-last-text (read-string "Search backward: ")))
+  (let* ((left nil)
+        (beg (edt-current-line))
+        (height (window-height))
+        (top-percent
+         (if (= 0 edt-top-scroll-margin) 10 edt-top-scroll-margin))
+        (bottom-percent
+         (if (= 0 edt-bottom-scroll-margin) 15 edt-bottom-scroll-margin))
+        (top-margin (/ (* height top-percent) 100))
+        (bottom-up-margin (+ 1 (/ (* height bottom-percent) 100)))
+        (bottom-margin (max beg (- height bottom-up-margin 1)))
+        (top (save-excursion (move-to-window-line top-margin) (point)))
+        (bottom (save-excursion (move-to-window-line bottom-margin) (point)))
+        (far (save-excursion
+               (goto-char bottom) (forward-line (- height 2)) (point))))
+    (if (search-backward edt-find-last-text)
+       (edt-set-match))
+    (and (< (point) top) (recenter (min beg top-margin))))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-find ()
+  "Find first occurrence of string in current direction and save it."
+  (interactive)
+  (set 'edt-find-last-text (read-string "Search: "))
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-find-forward t)
+      (edt-find-backward t)))
+
+
+;;;
+;;; FNDNXT
+;;;
+
+(defun edt-find-next-forward ()
+  "Find next occurrence of a string in forward direction."
+  (interactive)
+  (let* ((left nil)
+        (beg (edt-current-line))
+        (height (window-height))
+        (top-percent
+         (if (= 0 edt-top-scroll-margin) 10 edt-top-scroll-margin))
+        (bottom-percent
+         (if (= 0 edt-bottom-scroll-margin) 15 edt-bottom-scroll-margin))
+        (top-margin (/ (* height top-percent) 100))
+        (bottom-up-margin (+ 1 (/ (* height bottom-percent) 100)))
+        (bottom-margin (max beg (- height bottom-up-margin 1)))
+        (top (save-excursion (move-to-window-line top-margin) (point)))
+        (bottom (save-excursion (move-to-window-line bottom-margin) (point)))
+        (far (save-excursion
+               (goto-char bottom) (forward-line (- height 2)) (point))))
+    (forward-char 1)
+    (if (search-forward edt-find-last-text nil t)
+       (progn
+         (search-backward edt-find-last-text)
+         (edt-set-match)
+         (cond((> (point) far)
+               (setq left (save-excursion (forward-line height)))
+               (if (= 0 left) (recenter top-margin)
+                 (recenter (- left bottom-up-margin))))
+              (t
+               (and (> (point) bottom) (recenter bottom-margin)))))
+      (progn
+       (backward-char 1)
+       (error "Search failed: \"%s\"" edt-find-last-text))))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-find-next-backward ()
+  "Find next occurrence of a string in backward direction."
+  (interactive)
+  (let* ((left nil)
+        (beg (edt-current-line))
+        (height (window-height))
+        (top-percent
+         (if (= 0 edt-top-scroll-margin) 10 edt-top-scroll-margin))
+        (bottom-percent
+         (if (= 0 edt-bottom-scroll-margin) 15 edt-bottom-scroll-margin))
+        (top-margin (/ (* height top-percent) 100))
+        (bottom-up-margin (+ 1 (/ (* height bottom-percent) 100)))
+        (bottom-margin (max beg (- height bottom-up-margin 1)))
+        (top (save-excursion (move-to-window-line top-margin) (point)))
+        (bottom (save-excursion (move-to-window-line bottom-margin) (point)))
+        (far (save-excursion
+               (goto-char bottom) (forward-line (- height 2)) (point))))
+    (if (not (search-backward edt-find-last-text nil t))
+       (error "Search failed: \"%s\"" edt-find-last-text)
+      (progn
+       (edt-set-match)
+       (and (< (point) top) (recenter (min beg top-margin))))))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-find-next ()
+  "Find next occurrence of a string in current direction."
+  (interactive)
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-find-next-forward)
+    (edt-find-next-backward)))
+
+;;;
+;;; APPEND
+;;;
+
+(defun edt-append ()
+  "Append this kill region to last killed region."
+  (interactive "*")
+  (edt-check-selection)
+  (append-next-kill)
+  (kill-region (mark) (point))
+  (message "Selected text APPENDED to kill ring"))
+
+;;;
+;;; DEL L
+;;;
+
+(defun edt-delete-line (num)
+  "Delete from cursor up to and including the end of line mark.
+Argument NUM is the number of lines to delete."
+  (interactive "*p")
+  (edt-check-prefix num)
+  (let ((beg (point)))
+    (forward-line num)
+    (if (not (eq (preceding-char) ?\n))
+        (insert "\n"))
+    (setq edt-last-deleted-lines
+          (buffer-substring beg (point)))
+    (delete-region beg (point))))
+
+;;;
+;;; DEL EOL
+;;;
+
+(defun edt-delete-to-end-of-line (num)
+  "Delete from cursor up to but excluding the end of line mark.
+Argument NUM is the number of lines to delete."
+  (interactive "*p")
+  (edt-check-prefix num)
+  (let ((beg (point)))
+    (forward-char 1)
+    (end-of-line num)
+    (setq edt-last-deleted-lines
+          (buffer-substring beg (point)))
+    (delete-region beg (point))))
+
+;;;
+;;; SELECT
+;;;
+
+(defun edt-select-mode (arg)
+  "Turn EDT select mode off if ARG is nil; otherwise, turn EDT select mode on.
+In select mode, selected text is highlighted."
+  (if arg
+      (progn
+       (make-local-variable 'edt-select-mode)
+       (setq edt-select-mode 'edt-select-mode-current)
+       (setq rect-start-point (window-point)))
+    (progn
+      (kill-local-variable 'edt-select-mode)))
+  (force-mode-line-update))
+
+(defun edt-select ()
+  "Set mark at cursor and start text selection."
+  (interactive)
+  (set-mark-command nil))
+
+(defun edt-reset ()
+  "Cancel text selection."
+  (interactive)
+  (if edt-gnu-emacs19-p
+      (deactivate-mark)
+    (zmacs-deactivate-region)))
+
+;;;
+;;; CUT
+;;;
+
+(defun edt-cut ()
+  "Deletes selected text but copies to kill ring."
+  (interactive "*")
+  (edt-check-selection)
+  (kill-region (mark) (point))
+  (message "Selected text CUT to kill ring"))
+
+;;;
+;;; DELETE TO BEGINNING OF LINE
+;;;
+
+(defun edt-delete-to-beginning-of-line (num)
+  "Delete from cursor to beginning of line.
+Argument NUM is the number of lines to delete."
+  (interactive "*p")
+  (edt-check-prefix num)
+  (let ((beg (point)))
+    (edt-beginning-of-line num)
+    (setq edt-last-deleted-lines
+          (buffer-substring (point) beg))
+    (delete-region beg (point))))
+
+;;;
+;;; DEL W
+;;;
+
+(defun edt-delete-word (num)
+  "Delete from cursor up to but excluding first character of next word.
+Argument NUM is the number of words to delete."
+  (interactive "*p")
+  (edt-check-prefix num)
+  (let ((beg (point)))
+    (edt-word-forward num)
+    (setq edt-last-deleted-words (buffer-substring beg (point)))
+    (delete-region beg (point))))
+
+;;;
+;;; DELETE TO BEGINNING OF WORD
+;;;
+
+(defun edt-delete-to-beginning-of-word (num)
+  "Delete from cursor to beginning of word.
+Argument NUM is the number of words to delete."
+  (interactive "*p")
+  (edt-check-prefix num)
+  (let ((beg (point)))
+    (edt-word-backward num)
+    (setq edt-last-deleted-words (buffer-substring (point) beg))
+    (delete-region beg (point))))
+
+;;;
+;;; DEL C
+;;;
+
+(defun edt-delete-character (num)
+  "Delete character under cursor.
+Argument NUM is the number of characters to delete."
+  (interactive "*p")
+  (edt-check-prefix num)
+  (setq edt-last-deleted-chars
+        (buffer-substring (point) (min (point-max) (+ (point) num))))
+  (delete-region (point) (min (point-max) (+ (point) num))))
+
+;;;
+;;; DELETE CHAR
+;;;
+
+(defun edt-delete-previous-character (num)
+  "Delete character in front of cursor.
+Argument NUM is the number of characters to delete."
+  (interactive "*p")
+  (edt-check-prefix num)
+  (setq edt-last-deleted-chars
+        (buffer-substring (max (point-min) (- (point) num)) (point)))
+  (delete-region (max (point-min) (- (point) num)) (point)))
+
+;;;
+;;; UND L
+;;;
+
+(defun edt-undelete-line ()
+  "Undelete previous deleted line(s)."
+  (interactive "*")
+  (point-to-register 1)
+  (insert edt-last-deleted-lines)
+  (register-to-point 1))
+
+;;;
+;;; UND W
+;;;
+
+(defun edt-undelete-word ()
+  "Undelete previous deleted word(s)."
+  (interactive "*")
+  (point-to-register 1)
+  (insert edt-last-deleted-words)
+  (register-to-point 1))
+
+;;;
+;;; UND C
+;;;
+
+(defun edt-undelete-character ()
+  "Undelete previous deleted character(s)."
+  (interactive "*")
+  (point-to-register 1)
+  (insert edt-last-deleted-chars)
+  (register-to-point 1))
+
+;;;
+;;; REPLACE
+;;;
+
+(defun edt-replace ()
+  "Replace marked section with last CUT (killed) text."
+  (interactive "*")
+  (if (edt-check-match)
+      (replace-match (car kill-ring-yank-pointer))
+    (progn
+      (exchange-point-and-mark)
+      (let ((beg (point)))
+       (exchange-point-and-mark)
+       (delete-region beg (point)))
+      (yank))))
+
+;;;
+;;; SUBS
+;;;
+
+(defun edt-substitute (num)
+  "Replace the selected region with the contents of the CUT buffer and.
+Repeat the most recent FIND command.  (The Emacs kill ring is used as
+the CUT buffer.)
+Argument NUM is the repeat count.  A positive value indicates the of times
+to repeat the substitution.  A negative argument means replace all occurrences
+of the search text."
+  (interactive "p")
+  (cond ((or edt-select-mode (edt-check-match))
+        (while (and (not (= num 0)) (or edt-select-mode (edt-check-match)))
+          (edt-replace)
+          (edt-find-next)
+          (setq num (1- num))))
+       (t
+        (error "No selection active"))))
+
+(defun edt-set-match nil
+  "Set markers at match beginning and end."
+  ;; Add one to beginning mark so it stays with the first character of
+  ;;   the string even if characters are added just before the string.
+  (setq edt-match-beginning-mark (copy-marker (1+ (match-beginning 0))))
+  (setq edt-match-end-mark (copy-marker (match-end 0))))
+
+(defun edt-unset-match nil
+  "Unset match beginning and end markers."
+  (set-marker edt-match-beginning-mark nil)
+  (set-marker edt-match-end-mark nil))
+
+(defun edt-match-beginning nil
+  "Return the location of the last match beginning."
+  (1- (marker-position edt-match-beginning-mark)))
+
+(defun edt-match-end nil
+  "Return the location of the last match end."
+  (marker-position edt-match-end-mark))
+
+(defun edt-check-match nil
+  "Return t if point is between edt-match markers.
+Otherwise sets the edt-match markers to nil and returns nil."
+  ;; make sure 1- marker is in this buffer
+  ;;           2- point is at or after beginning marker
+  ;;           3- point is before ending marker, or in the case of
+  ;;              zero length regions (like bol, or eol) that the
+  ;;              beginning, end, and point are equal.
+  (cond ((and
+         (equal (marker-buffer edt-match-beginning-mark) (current-buffer))
+         (>= (point) (1- (marker-position edt-match-beginning-mark)))
+         (or
+          (< (point) (marker-position edt-match-end-mark))
+          (and (= (1- (marker-position edt-match-beginning-mark))
+                  (marker-position edt-match-end-mark))
+               (= (marker-position edt-match-end-mark) (point))))) t)
+       (t
+        (edt-unset-match) nil)))
+
+(defun edt-show-match-markers nil
+  "Show the values of the match markers."
+  (interactive)
+  (if (markerp edt-match-beginning-mark)
+      (let ((beg (marker-position edt-match-beginning-mark)))
+       (message "(%s, %s) in %s -- current %s in %s"
+                (if beg (1- beg) nil)
+                (marker-position edt-match-end-mark)
+                (marker-buffer edt-match-end-mark)
+                (point) (current-buffer)))))
+
+
+;;;
+;;; ADVANCE
+;;;
+
+(defun edt-advance ()
+  "Set movement direction forward.
+Also, execute command specified if in Minibuffer."
+  (interactive)
+  (setq edt-direction-string edt-forward-string)
+  (force-mode-line-update)
+  (if (string-equal " *Minibuf"
+                    (substring (buffer-name) 0 (min (length (buffer-name)) 9)))
+      (exit-minibuffer))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+
+;;;
+;;; BACKUP
+;;;
+
+(defun edt-backup ()
+  "Set movement direction backward.
+Also, execute command specified if in Minibuffer."
+  (interactive)
+  (setq edt-direction-string edt-backward-string)
+  (force-mode-line-update)
+  (if (string-equal " *Minibuf"
+                    (substring (buffer-name) 0 (min (length (buffer-name)) 9)))
+      (exit-minibuffer))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+
+;;;
+;;; CHNGCASE
+;;;
+;; This function is based upon Jeff Kowalski's case-flip function in his
+;; tpu.el.
+
+(defun edt-change-case (num)
+  "Change the case of specified characters.
+If text selection IS active, then characters between the cursor and mark are
+changed.  If text selection is NOT active, there are two cases.  First, if the
+current direction is ADVANCE, then the prefix number of character(s) under and
+following cursor are changed.  Second, if the current direction is BACKUP, then
+the prefix number of character(s) before the cursor are changed.  Accepts a
+positive prefix for the number of characters to change, but the prefix is
+ignored if text selection is active.
+Argument NUM is the numbers of consecutive characters to change."
+  (interactive "*p")
+  (edt-check-prefix num)
+  (if edt-select-mode
+      (let ((end (max (mark) (point)))
+            (point-save (point)))
+        (goto-char (min (point) (mark)))
+        (while (not (eq (point) end))
+          (funcall (if (<= ?a (following-char))
+                       'upcase-region 'downcase-region)
+                   (point) (1+ (point)))
+          (forward-char 1))
+        (goto-char point-save))
+    (progn
+      (if (string= edt-direction-string edt-backward-string)
+         (backward-char num))
+      (while (> num 0)
+       (funcall (if (<= ?a (following-char))
+                    'upcase-region 'downcase-region)
+                (point) (1+ (point)))
+       (forward-char 1)
+       (setq num (1- num))))))
+
+;;;
+;;; DEFINE KEY
+;;;
+
+(defun edt-define-key ()
+  "Assign an interactively-callable function to a specified key sequence.
+The current key definition is saved in `edt-last-replaced-key-definition'.
+Use `edt-restore-key' to restore last replaced key definition."
+  (interactive)
+  (if edt-x-emacs19-p (setq zmacs-region-stays t))
+  (let (edt-function
+       edt-key-definition)
+    (setq edt-key-definition
+         (read-key-sequence "Press the key to be defined: "))
+    (if (if edt-gnu-emacs19-p
+           (string-equal "\C-m" edt-key-definition)
+         (string-equal "\C-m" (events-to-keys edt-key-definition)))
+        (message "Key not defined")
+      (progn
+       (setq edt-function (read-command "Enter command name: "))
+       (if (string-equal "" edt-function)
+           (message "Key not defined")
+         (progn
+           (setq edt-last-replaced-key-definition
+                 (lookup-key (current-global-map) edt-key-definition))
+           (define-key (current-global-map)
+             edt-key-definition edt-function)))))))
+
+;;;
+;;; FORM FEED INSERT
+;;;
+
+(defun edt-form-feed-insert (num)
+  "Insert form feed character at cursor position.
+Argument NUM is the number of form feeds to insert."
+  (interactive "*p")
+  (edt-check-prefix num)
+  (while (> num 0)
+    (insert ?\f)
+    (setq num (1- num))))
+
+;;;
+;;; TAB INSERT
+;;;
+
+(defun edt-tab-insert (num)
+  "Insert tab character at cursor position.
+Argument NUM is the number of tabs to insert."
+  (interactive "*p")
+  (edt-check-prefix num)
+  (while (> num 0)
+    (insert ?\t)
+    (setq num (1- num))))
+
+;;;
+;;; Check Prefix
+;;;
+
+(defun edt-check-prefix (num)
+  "Indicate error if prefix is not positive.
+Argument NUM is the prefix value tested."
+  (if (<= num 0)
+      (error "Prefix must be positive")))
+
+;;;
+;;; Check Selection
+;;;
+
+(defun edt-check-selection ()
+  "Indicate error if EDT selection is not active."
+  (if (not edt-select-mode)
+      (error "Selection NOT active")))
+
+;;;
+;;; Scroll Margins
+;;;
+
+(defun edt-top-check (beg lines)
+  "Enforce scroll margin at the top of screen.
+Argument BEG is the starting line number before cursor was moved.
+Argument LINES is the number of lines the cursor moved toward the top."
+  (let ((margin         (/ (* (window-height) edt-top-scroll-margin) 100)))
+    (cond ((< beg margin) (recenter beg))
+         ((< (- beg lines) margin) (recenter margin)))))
+
+(defun edt-bottom-check (beg lines)
+  "Enforce scroll margin at the bottom of screen.
+Argument BEG is the starting line number before cursor was moved.
+Argument LINES is the number of lines the cursor moved toward the bottom."
+  (let* ((height (window-height))
+                (margin (+ 1 (/ (* height edt-bottom-scroll-margin) 100)))
+                ;; subtract 1 from height because it includes mode line
+                (difference (- height margin 1)))
+    (cond ((> beg difference) (recenter beg))
+                 ((and edt-x-emacs19-p (> (+ beg lines 1) difference))
+                  (recenter (- margin)))
+                 ((> (+ beg lines) difference) (recenter (- margin))))))
+
+(defun edt-current-line nil
+  "Return the vertical position of point in the selected window.
+Top line is 0.  Counts each text line only once, even if it wraps."
+  (+ (count-lines (window-start) (point)) (if (= (current-column) 0) 1 0) -1))
+
+;;;###autoload
+(defun edt-set-scroll-margins (top bottom)
+  "Set scroll margins.
+Argument TOP is the top margin in number of lines or percent of window.
+Argument BOTTOM is the bottom margin in number of lines or percent of window."
+  (interactive
+   "sEnter top scroll margin (N lines or N%% or RETURN for current value): \
+\nsEnter bottom scroll margin (N lines or N%% or RETURN for current value): ")
+  ;; set top scroll margin
+  (or (string= top "")
+      (if (string= "%" (substring top -1))
+         (setq edt-top-scroll-margin (string-to-int top))
+       (setq edt-top-scroll-margin
+             (/ (1- (+ (* (string-to-int top) 100) (window-height)))
+                (window-height)))))
+  ;; set bottom scroll margin
+  (or (string= bottom "")
+      (if (string= "%" (substring bottom -1))
+         (setq edt-bottom-scroll-margin (string-to-int bottom))
+       (setq edt-bottom-scroll-margin
+             (/ (1- (+ (* (string-to-int bottom) 100) (window-height)))
+                (window-height)))))
+  ;; report scroll margin settings if running interactively
+  (and (interactive-p)
+       (message "Scroll margins set.  Top = %s%%, Bottom = %s%%"
+               edt-top-scroll-margin edt-bottom-scroll-margin)))
+
+\f
+;;;;
+;;;; ENHANCEMENTS AND ADDITIONS FOR EDT KEYPAD MODE
+;;;;
+
+;;;
+;;; Several enhancements and additions to EDT keypad mode commands are
+;;; provided here.  Some of these have been motivated by similar
+;;; TPU/EVE and EVE-Plus commands.  Others are new.
+
+;;;
+;;; CHANGE DIRECTION
+;;;
+
+(defun edt-change-direction ()
+  "Toggle movement direction."
+  (interactive)
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-backup)
+    (edt-advance)))
+
+;;;
+;;; TOGGLE SELECT
+;;;
+
+(defun edt-toggle-select ()
+  "Toggle to start (or cancel) text selection."
+  (interactive)
+  (if edt-select-mode
+      (edt-reset)
+    (edt-select)))
+
+;;;
+;;; SENTENCE
+;;;
+
+(defun edt-sentence-forward (num)
+  "Move forward to start of next sentence.
+Argument NUM is the positive number of sentences to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (let* ((left nil)
+        (beg (edt-current-line))
+        (height (window-height))
+        (top-percent
+         (if (= 0 edt-top-scroll-margin) 10 edt-top-scroll-margin))
+        (bottom-percent
+         (if (= 0 edt-bottom-scroll-margin) 15 edt-bottom-scroll-margin))
+        (top-margin (/ (* height top-percent) 100))
+        (bottom-up-margin (+ 1 (/ (* height bottom-percent) 100)))
+        (bottom-margin (max beg (- height bottom-up-margin 1)))
+        (top (save-excursion (move-to-window-line top-margin) (point)))
+        (bottom (save-excursion (move-to-window-line bottom-margin) (point)))
+        (far (save-excursion
+               (goto-char bottom) (forward-line (- height 2)) (point))))
+    (if (eobp)
+       (progn
+         (error "End of buffer"))
+      (progn
+       (forward-sentence num)
+       (forward-word 1)
+       (backward-sentence)))
+    (cond((> (point) far)
+         (setq left (save-excursion (forward-line height)))
+         (if (= 0 left) (recenter top-margin)
+           (recenter (- left bottom-up-margin))))
+        (t
+         (and (> (point) bottom) (recenter bottom-margin)))))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-sentence-backward (num)
+  "Move backward to next sentence beginning.
+Argument NUM is the positive number of sentences to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (let* ((left nil)
+        (beg (edt-current-line))
+        (height (window-height))
+        (top-percent
+         (if (= 0 edt-top-scroll-margin) 10 edt-top-scroll-margin))
+        (bottom-percent
+         (if (= 0 edt-bottom-scroll-margin) 15 edt-bottom-scroll-margin))
+        (top-margin (/ (* height top-percent) 100))
+        (bottom-up-margin (+ 1 (/ (* height bottom-percent) 100)))
+        (bottom-margin (max beg (- height bottom-up-margin 1)))
+        (top (save-excursion (move-to-window-line top-margin) (point)))
+        (bottom (save-excursion (move-to-window-line bottom-margin) (point)))
+        (far (save-excursion
+               (goto-char bottom) (forward-line (- height 2)) (point))))
+    (if (eobp)
+       (progn
+         (error "End of buffer"))
+      (backward-sentence num))
+    (and (< (point) top) (recenter (min beg top-margin))))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-sentence (num)
+  "Move in current direction to next sentence.
+Argument NUM is the positive number of sentences to move."
+  (interactive "p")
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-sentence-forward num)
+    (edt-sentence-backward num)))
+
+;;;
+;;; PARAGRAPH
+;;;
+
+(defun edt-paragraph-forward (num)
+  "Move forward to beginning of paragraph.
+Argument NUM is the positive number of paragraphs to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (let* ((left nil)
+        (beg (edt-current-line))
+        (height (window-height))
+        (top-percent
+         (if (= 0 edt-top-scroll-margin) 10 edt-top-scroll-margin))
+        (bottom-percent
+         (if (= 0 edt-bottom-scroll-margin) 15 edt-bottom-scroll-margin))
+        (top-margin (/ (* height top-percent) 100))
+        (bottom-up-margin (+ 1 (/ (* height bottom-percent) 100)))
+        (bottom-margin (max beg (- height bottom-up-margin 1)))
+        (top (save-excursion (move-to-window-line top-margin) (point)))
+        (bottom (save-excursion (move-to-window-line bottom-margin) (point)))
+        (far (save-excursion
+               (goto-char bottom) (forward-line (- height 2)) (point))))
+    (while (> num 0)
+      (forward-paragraph (+ num 1))
+      (start-of-paragraph-text)
+      (if (eolp)
+         (next-line 1))
+      (setq num (1- num)))
+    (cond((> (point) far)
+         (setq left (save-excursion (forward-line height)))
+         (if (= 0 left) (recenter top-margin)
+           (recenter (- left bottom-up-margin))))
+        (t
+         (and (> (point) bottom) (recenter bottom-margin)))))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-paragraph-backward (num)
+  "Move backward to beginning of paragraph.
+Argument NUM is the positive number of paragraphs to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (let* ((left nil)
+        (beg (edt-current-line))
+        (height (window-height))
+        (top-percent
+         (if (= 0 edt-top-scroll-margin) 10 edt-top-scroll-margin))
+        (bottom-percent
+         (if (= 0 edt-bottom-scroll-margin) 15 edt-bottom-scroll-margin))
+        (top-margin (/ (* height top-percent) 100))
+        (bottom-up-margin (+ 1 (/ (* height bottom-percent) 100)))
+        (bottom-margin (max beg (- height bottom-up-margin 1)))
+        (top (save-excursion (move-to-window-line top-margin) (point)))
+        (bottom (save-excursion (move-to-window-line bottom-margin) (point)))
+        (far (save-excursion
+               (goto-char bottom) (forward-line (- height 2)) (point))))
+    (while (> num 0)
+      (start-of-paragraph-text)
+      (setq num (1- num)))
+    (and (< (point) top) (recenter (min beg top-margin))))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-paragraph (num)
+  "Move in current direction to next paragraph.
+Argument NUM is the positive number of paragraphs to move."
+  (interactive "p")
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-paragraph-forward num)
+    (edt-paragraph-backward num)))
+
+;;;
+;;; RESTORE KEY
+;;;
+
+(defun edt-restore-key ()
+  "Restore last replaced key definition.
+Definition is stored in `edt-last-replaced-key-definition'."
+  (interactive)
+  (if edt-x-emacs19-p (setq zmacs-region-stays t))
+  (if edt-last-replaced-key-definition
+      (progn
+        (let (edt-key-definition)
+          (set 'edt-key-definition
+               (read-key-sequence "Press the key to be restored: "))
+         (if (if edt-gnu-emacs19-p
+                 (string-equal "\C-m" edt-key-definition)
+               (string-equal "\C-m" (events-to-keys edt-key-definition)))
+              (message "Key not restored")
+           (progn
+             (define-key (current-global-map)
+               edt-key-definition edt-last-replaced-key-definition)
+             (if edt-gnu-emacs19-p
+                 (message "Key definition for %s has been restored."
+                          edt-key-definition)
+               (message "Key definition for %s has been restored."
+                        (events-to-keys edt-key-definition)))))))
+    (error "No replaced key definition to restore!")))
+
+;;;
+;;; WINDOW TOP
+;;;
+
+(defun edt-window-top ()
+  "Move the cursor to the top of the window."
+  (interactive)
+  (let ((start-column (current-column)))
+    (move-to-window-line 0)
+    (move-to-column start-column))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+;;;
+;;; WINDOW BOTTOM
+;;;
+
+(defun edt-window-bottom ()
+  "Move the cursor to the bottom of the window."
+  (interactive)
+  (let ((start-column (current-column)))
+    (move-to-window-line (- (window-height) 2))
+    (move-to-column start-column))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+;;;
+;;; SCROLL WINDOW LINE
+;;;
+
+(defun edt-scroll-window-forward-line ()
+  "Move window forward one line leaving cursor at position in window."
+  (interactive)
+  (scroll-up 1)
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-scroll-window-backward-line ()
+  "Move window backward one line leaving cursor at position in window."
+  (interactive)
+  (scroll-down 1)
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+(defun edt-scroll-line ()
+  "Move window one line in current direction."
+  (interactive)
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-scroll-window-forward-line)
+    (edt-scroll-window-backward-line)))
+
+;;;
+;;; SCROLL WINDOW
+;;;
+;;; Scroll a window (less one line) at a time.  Leave cursor in center of
+;;; window.
+
+(defun edt-scroll-window-forward (num)
+  "Scroll forward one window in buffer, less one line.
+Argument NUM is the positive number of windows to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (scroll-up (- (* (window-height) num) 2))
+  (edt-line-forward (/ (- (window-height) 1) 2)))
+
+(defun edt-scroll-window-backward (num)
+  "Scroll backward one window in buffer, less one line.
+Argument NUM is the positive number of windows to move."
+  (interactive "p")
+  (edt-check-prefix num)
+  (scroll-down (- (* (window-height) num) 2))
+  (edt-line-backward (/ (- (window-height) 1) 2)))
+
+(defun edt-scroll-window (num)
+  "Scroll one window in buffer, less one line, in current direction.
+Argument NUM is the positive number of windows to move."
+  (interactive "p")
+  (if (equal edt-direction-string edt-forward-string)
+      (edt-scroll-window-forward num)
+    (edt-scroll-window-backward num)))
+
+;;;
+;;; LINE TO BOTTOM OF WINDOW
+;;;
+
+(defun edt-line-to-bottom-of-window ()
+  "Move the current line to the bottom of the window."
+  (interactive)
+  (recenter -1)
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+;;;
+;;; LINE TO TOP OF WINDOW
+;;;
+
+(defun edt-line-to-top-of-window ()
+  "Move the current line to the top of the window."
+  (interactive)
+  (recenter 0)
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+;;;
+;;; LINE TO MIDDLE OF WINDOW
+;;;
+
+(defun edt-line-to-middle-of-window ()
+  "Move window so line with cursor is in the middle of the window."
+  (interactive)
+  (recenter '(4))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+;;;
+;;; GOTO PERCENTAGE
+;;;
+
+(defun edt-goto-percentage (num)
+  "Move to specified percentage in buffer from top of buffer.
+Argument NUM is the percentage into the buffer to move."
+  (interactive "NGoto-percentage: ")
+  (if (or (> num 100) (< num 0))
+      (error "Percentage %d out of range 0 < percent < 100" num)
+    (goto-char (/ (* (point-max) num) 100)))
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+;;;
+;;; FILL REGION
+;;;
+
+(defun edt-fill-region ()
+  "Fill selected text."
+  (interactive "*")
+  (edt-check-selection)
+  (fill-region (point) (mark)))
+
+;;;
+;;; INDENT OR FILL REGION
+;;;
+
+(defun edt-indent-or-fill-region ()
+  "Fill region in text modes, indent region in programming language modes."
+  (interactive "*")
+  (if (string= paragraph-start "$\\|\f")
+      (indent-region (point) (mark) nil)
+    (fill-region (point) (mark))))
+
+;;;
+;;; MARK SECTION WISELY
+;;;
+
+(defun edt-mark-section-wisely ()
+  "Mark the section in a manner consistent with the `major-mode'.
+Uses `mark-defun' for emacs-lisp and Lisp,
+mark-c-function for C,
+mark-fortran-subsystem for fortran,
+and `mark-paragraph' for other modes."
+  (interactive)
+  (if edt-select-mode
+      (progn
+        (edt-reset))
+    (progn
+      (cond  ((or (eq major-mode 'emacs-lisp-mode)
+                 (eq major-mode 'lisp-mode))
+             (mark-defun)
+             (message "Lisp defun selected"))
+            ((eq major-mode 'c-mode)
+             (mark-c-function)
+             (message "C function selected"))
+            ((eq major-mode 'fortran-mode)
+             (mark-fortran-subprogram)
+             (message "Fortran subprogram selected"))
+            (t (mark-paragraph)
+               (message "Paragraph selected"))))))
+
+;;;
+;;; COPY
+;;;
+
+(defun edt-copy ()
+  "Copy selected region to kill ring, but don't delete it!"
+  (interactive)
+  (edt-check-selection)
+  (copy-region-as-kill (mark) (point))
+  (edt-reset)
+  (message "Selected text COPIED to kill ring"))
+
+;;;
+;;; CUT or COPY
+;;;
+
+(defun edt-cut-or-copy ()
+  "Cuts (or copies) selected text to kill ring.
+Cuts selected text if `buffer-read-only' is nil.
+Copies selected text if `buffer-read-only' is t."
+  (interactive)
+  (if buffer-read-only
+      (edt-copy)
+    (edt-cut)))
+
+;;;
+;;; DELETE ENTIRE LINE
+;;;
+
+(defun edt-delete-entire-line ()
+  "Delete entire line regardless of cursor position in the line."
+  (interactive "*")
+  (beginning-of-line)
+  (edt-delete-line 1))
+
+;;;
+;;; DUPLICATE LINE
+;;;
+
+(defun edt-duplicate-line (num)
+  "Duplicate the line of text containing the cursor.
+Argument NUM is the number of times to duplicate the line."
+  (interactive "*p")
+  (edt-check-prefix num)
+  (let ((old-column (current-column))
+        (count num))
+    (edt-delete-entire-line)
+    (edt-undelete-line)
+    (while (> count 0)
+      (edt-undelete-line)
+      (setq count (1- count)))
+    (edt-line-forward num)
+    (move-to-column old-column)))
+
+;;;
+;;; DUPLICATE WORD
+;;;
+
+(defun edt-duplicate-word()
+  "Duplicate word (or rest of word) found directly above cursor, if any."
+  (interactive "*")
+  (let ((start (point))
+        (start-column (current-column)))
+    (forward-line -1)
+    (move-to-column start-column)
+    (if (and (not (equal start (point)))
+             (not (eolp)))
+        (progn
+          (if (and (equal ?\t (preceding-char))
+                   (< start-column (current-column)))
+              (backward-char))
+          (let ((beg (point)))
+            (edt-one-word-forward)
+            (setq edt-last-copied-word (buffer-substring beg (point))))
+          (forward-line)
+          (move-to-column start-column)
+          (insert edt-last-copied-word))
+      (progn
+       (if (not (equal start (point)))
+           (forward-line))
+       (move-to-column start-column)
+       (error "Nothing to duplicate!")))))
+
+;;;
+;;; KEY NOT ASSIGNED
+;;;
+
+(defun edt-key-not-assigned ()
+  "Displays message that key has not been assigned to a function."
+  (interactive)
+  (error "Key not assigned"))
+
+;;;
+;;; TOGGLE CAPITALIZATION OF WORD
+;;;
+
+(defun edt-toggle-capitalization-of-word ()
+  "Toggle the capitalization of the current word and move forward to next."
+  (interactive "*")
+  (edt-one-word-forward)
+  (edt-one-word-backward)
+  (edt-change-case 1)
+  (edt-one-word-backward)
+  (edt-one-word-forward))
+
+;;;
+;;; ELIMINATE ALL TABS
+;;;
+
+(defun edt-eliminate-all-tabs ()
+  "Convert all tabs to spaces in the entire buffer."
+  (interactive "*")
+  (untabify (point-min) (point-max))
+  (message "TABS converted to SPACES"))
+
+;;;
+;;; DISPLAY THE TIME
+;;;
+
+(defun edt-display-the-time ()
+  "Display the current time."
+  (interactive)
+  (if edt-x-emacs19-p (setq zmacs-region-stays t))
+  (set 'time-string (current-time-string))
+  (message "%s" time-string))
+
+;;;
+;;; LEARN
+;;;
+
+(defun edt-learn ()
+  "Learn a sequence of key strokes to bind to a key."
+  (interactive)
+  (if (eq defining-kbd-macro t)
+      (edt-remember)
+    (start-kbd-macro nil)))
+
+;;;
+;;; REMEMBER
+;;;
+
+(defun edt-remember ()
+  "Store the sequence of key strokes started by `edt-learn' to a key."
+  (interactive)
+  (if (eq defining-kbd-macro nil)
+      (error "Nothing to remember!")
+    (progn
+      (end-kbd-macro nil)
+      (let (edt-key-definition)
+       (set 'edt-key-definition
+            (read-key-sequence "Enter key for binding: "))
+       (if (if edt-gnu-emacs19-p
+               (string-equal "\C-m" edt-key-definition)
+             (string-equal "\C-m" (events-to-keys edt-key-definition)))
+           (message "Key sequence not remembered")
+         (progn
+           (set 'edt-learn-macro-count (+ edt-learn-macro-count 1))
+           (setq edt-last-replaced-key-definition
+                 (lookup-key (current-global-map)
+                             edt-key-definition))
+           (define-key (current-global-map) edt-key-definition
+             (name-last-kbd-macro
+              (intern (concat "last-learned-sequence-"
+                              (int-to-string edt-learn-macro-count)))))))))))
+
+;;;
+;;; EXIT
+;;;
+
+(defun edt-exit ()
+  "Save current buffer, ask to save other buffers, and then exit Emacs."
+  (interactive)
+  (save-buffer)
+  (save-buffers-kill-emacs))
+
+;;;
+;;; QUIT
+;;;
+
+(defun edt-quit ()
+  "Quit Emacs without saving buffer modifications.
+Warn user that modifications will be lost."
+  (interactive)
+  (let ((list (buffer-list))
+       (working t))
+    (while (and list working)
+      (let ((buffer (car list)))
+       (if (and (buffer-file-name buffer) (buffer-modified-p buffer))
+            (if (edt-y-or-n-p
+                "Modifications will not be saved, continue quitting? ")
+               (kill-emacs)
+             (setq working nil)))
+       (setq list (cdr list))))
+    (if working (kill-emacs))))
+
+;;;
+;;; SPLIT WINDOW
+;;;
+
+(defun edt-split-window ()
+  "Split current window and place cursor in the new window."
+  (interactive)
+  (split-window)
+  (other-window 1)
+  (if edt-x-emacs19-p (setq zmacs-region-stays t)))
+
+;;;
+;;; COPY RECTANGLE
+;;;
+
+(defun edt-copy-rectangle ()
+  "Copy a rectangle of text between mark and cursor to register."
+  (interactive)
+  (edt-check-selection)
+  (copy-rectangle-to-register 3 (region-beginning) (region-end) nil)
+  (edt-reset)
+  (message "Selected rectangle COPIED to register"))
+
+;;;
+;;; CUT RECTANGLE
+;;;
+
+(defun edt-cut-rectangle-overstrike-mode ()
+  "Cut a rectangle of text between mark and cursor to register.
+Replace cut characters with spaces and moving cursor back to
+upper left corner."
+  (interactive "*")
+  (edt-check-selection)
+  (setq edt-rect-start-point (region-beginning))
+  (picture-clear-rectangle-to-register (region-beginning) (region-end) 3)
+  (set-window-point (get-buffer-window (window-buffer)) edt-rect-start-point)
+  (message "Selected rectangle CUT to register"))
+
+(defun edt-cut-rectangle-insert-mode ()
+  "Cut a rectangle of text between mark and cursor to register.
+Move cursor back to upper left corner."
+  (interactive "*")
+  (edt-check-selection)
+  (setq edt-rect-start-point (region-beginning))
+  (picture-clear-rectangle-to-register (region-beginning) (region-end) 3 t)
+  (fixup-whitespace)
+  (set-window-point (get-buffer-window (window-buffer)) edt-rect-start-point)
+  (message "Selected rectangle CUT to register"))
+
+(defun edt-cut-rectangle ()
+  "Cut a rectangular region of text to register.
+If overwrite mode is active, cut text is replaced with whitespace."
+  (interactive "*")
+  (if overwrite-mode
+      (edt-cut-rectangle-overstrike-mode)
+    (edt-cut-rectangle-insert-mode)))
+
+;;;
+;;; PASTE RECTANGLE
+;;;
+
+(defun edt-paste-rectangle-overstrike-mode ()
+  "Paste a rectangular region of text from register, replacing text at cursor."
+  (interactive "*")
+  (picture-yank-rectangle-from-register 3))
+
+(defun edt-paste-rectangle-insert-mode ()
+  "Paste previously deleted rectangular region, inserting text at cursor."
+  (interactive "*")
+  (picture-yank-rectangle-from-register 3 t))
+
+(defun edt-paste-rectangle ()
+  "Paste a rectangular region of text.
+If overwrite mode is active, existing text is replace with text from register."
+  (interactive)
+  (if overwrite-mode
+      (edt-paste-rectangle-overstrike-mode)
+    (edt-paste-rectangle-insert-mode)))
+
+;;;
+;;; DOWNCASE REGION
+;;;
+
+(defun edt-lowercase ()
+  "Change specified characters to lower case.
+If text selection IS active, then characters between the cursor and
+mark are changed.  If text selection is NOT active, there are two
+situations.  If the current direction is ADVANCE, then the word under
+the cursor is changed to lower case and the cursor is moved to rest at
+the beginning of the next word.  If the current direction is BACKUP,
+the word prior to the word under the cursor is changed to lower case
+and the cursor is left to rest at the beginning of that word."
+  (interactive "*")
+  (if edt-select-mode
+      (progn
+       (downcase-region (mark) (point)))
+    (progn
+      ;; Move to beginning of current word.
+      (if (and
+          (not (bobp))
+          (not (eobp))
+          (not (bolp))
+          (not (eolp))
+          (not (eq ?\  (char-syntax (preceding-char))))
+          (not (memq (preceding-char) edt-word-entities))
+          (not (memq (following-char) edt-word-entities)))
+         (edt-one-word-backward))
+      (if (equal edt-direction-string edt-backward-string)
+         (edt-one-word-backward))
+      (let ((beg (point)))
+       (edt-one-word-forward)
+       (downcase-region beg (point)))
+      (if (equal edt-direction-string edt-backward-string)
+         (edt-one-word-backward)))))
+
+;;;
+;;; UPCASE REGION
+;;;
+
+(defun edt-uppercase ()
+  "Change specified characters to upper case.
+If text selection IS active, then characters between the cursor and
+mark are changed.  If text selection is NOT active, there are two
+situations.  If the current direction is ADVANCE, then the word under
+the cursor is changed to upper case and the cursor is moved to rest at
+the beginning of the next word.  If the current direction is BACKUP,
+the word prior to the word under the cursor is changed to upper case
+and the cursor is left to rest at the beginning of that word."
+  (interactive "*")
+  (if edt-select-mode
+      (progn
+       (upcase-region (mark) (point)))
+    (progn
+      ;; Move to beginning of current word.
+      (if (and
+          (not (bobp))
+          (not (eobp))
+          (not (bolp))
+          (not (eolp))
+          (not (eq ?\  (char-syntax (preceding-char))))
+          (not (memq (preceding-char) edt-word-entities))
+          (not (memq (following-char) edt-word-entities)))
+         (edt-one-word-backward))
+      (if (equal edt-direction-string edt-backward-string)
+         (edt-one-word-backward))
+      (let ((beg (point)))
+       (edt-one-word-forward)
+       (upcase-region beg (point)))
+      (if (equal edt-direction-string edt-backward-string)
+         (edt-one-word-backward)))))
+
+;;;
+;;;  Functions used in loading LK-201 key mapping file.
+;;;
+(defvar edt-last-answer nil
+  "Most recent response to `edt-y-or-n-p'.")
+
+(defun edt-y-or-n-p (prompt &optional not-yes)
+  "Prompt for a y or n answer with positive default.
+Like Emacs `y-or-n-p', also accepts space as y and DEL as n.
+Argument PROMPT is the prompt string.
+Optional argument NOT-YES changes the default to negative."
+  (message "%s[%s]" prompt (if not-yes "n" "y"))
+  (let ((doit t))
+    (while doit
+      (setq doit nil)
+      (let ((ans (read-char)))
+       (cond ((or (= ans ?y) (= ans ?Y) (= ans ?\ ))
+              (setq edt-last-answer t))
+             ((or (= ans ?n) (= ans ?N) (= ans ?\C-?))
+              (setq edt-last-answer nil))
+             ((= ans ?\r) (setq edt-last-answer (not not-yes)))
+             (t
+              (setq doit t) (beep)
+              (message "Please answer y or n.  %s[%s]"
+                       prompt (if not-yes "n" "y")))))))
+  edt-last-answer)
+\f
+;;;
+;;; INITIALIZATION COMMANDS.
+;;;
+
+;;;
+;;;  Function used to load LK-201 key mapping file generated by edt-mapper.el.
+;;;
+(defun edt-load-keys (file)
+  "Load the LK-201 key mapping FILE generated by edt-mapper.el.
+If FILE is nil, which is the normal case, try to load a default file.
+The default file names are based upon the window system, terminal
+type, and version of Emacs in use: GNU Emacs or XEmacs (aka Lucid
+Emacs).  If a default file does not exist, ask user if one should be
+created."
+  (interactive "fKey definition file: ")
+  (cond (file
+        (setq file (expand-file-name file)))
+       (edt-keys-file
+        (setq file (expand-file-name edt-keys-file)))
+       (t
+        (setq file
+              (expand-file-name
+               (concat
+                "~/.edt-" edt-emacs-variant
+                (if edt-term (concat "-" edt-term))
+                (if edt-xserver (concat "-" edt-xserver))
+                (if edt-window-system
+                    (concat "-" (upcase (symbol-name edt-window-system))))
+                "-keys")))))
+  (cond ((file-readable-p file)
+        (load-file file))
+       (t
+        (switch-to-buffer "*scratch*")
+        (erase-buffer)
+        (insert "
+
+     Ack!!  You're running the Enhanced EDT Emulation without loading an
+     EDT key mapping file.  To create an EDT key mapping file, run the
+     edt-mapper.el program.  It is safest to run it from an Emacs loaded
+     without any of your own customizations found in your .emacs file, etc.
+     The reason for this is that some user customizations confuse edt-mapper.
+     You can do this by quitting Emacs and then invoking Emacs again as
+     follows:
+
+          emacs -q -l edt-mapper.el
+
+     [NOTE:  If you do nothing out of the ordinary in your .emacs file, and
+     the search for edt-mapper.el is successful, you can try running it now.]
+
+     The file edt-mapper.el includes these same directions on how to
+     use it!  Perhaps it's lying around here someplace. \n     ")
+        (let ((file "edt-mapper.el")
+              (found nil)
+              (path nil)
+              (search-list (append (list (expand-file-name ".")) load-path)))
+          (while (and (not found) search-list)
+            (setq path (concat (car search-list)
+                               (if (string-match "/$" (car search-list)) "" "/")
+                               file))
+            (if (and (file-exists-p path) (not (file-directory-p path)))
+                (setq found t))
+            (setq search-list (cdr search-list)))
+          (cond (found
+                 (insert (format
+                          "Ah yes, there it is, in \n\n       %s \n\n" path))
+                 (if (edt-y-or-n-p "Do you want to run it now? ")
+                     (load-file path)
+                   (error "EDT Emulation not configured")))
+                (t
+                 (insert "Nope, I can't seem to find it.  :-(\n\n")
+                 (sit-for 20)
+                 (error "EDT Emulation not configured")))))))
+
+;;;
+;;;  Turning the EDT Emulation on and off.
+;;;
+
+;;;###autoload
+(defun edt-emulation-on ()
+  "Turn on EDT Emulation."
+  (interactive)
+  ;; If using pc window system (MS-DOS), set terminal type to pc.
+  ;; If not a window system (GNU) or a tty window system (XEmacs),
+  ;; get terminal type.
+  (if (eq edt-window-system 'pc)
+      (setq edt-term "pc")
+    (if (or (not edt-window-system) (eq edt-window-system 'tty))
+       (setq edt-term (getenv "TERM"))))
+  ;; Look for for terminal configuration file for this terminal type.
+  ;; Otherwise, load the user's custom configuration file.
+  (if (or (not edt-window-system) (memq edt-window-system '(pc tty)))
+      (progn
+       ;; Load terminal-specific configuration file, if it exists for this
+       ;; terminal type.  Note: All DEC VT series terminals are supported
+       ;; by the same terminal configuration file: edt-vt100.el.
+       (if (string-equal "vt" (substring edt-term 0 (min (length edt-term) 2)))
+           (setq edt-term "vt100"))
+       (let ((term edt-term)
+             hyphend)
+         (while (and term
+                     (not (load (concat "edt-" term) t t)))
+           ;; Strip off last hyphen and what follows, then try again
+           (if (setq hyphend (string-match "[-_][^-_]+$" term))
+               (setq term (substring term 0 hyphend))
+             (setq term nil)))
+         ;; If no terminal-specific configuration file exists, load user's
+         ;; custom EDT terminal configuration file.
+         ;; If this is a pc running MS-DOS, then custom configuration files
+         ;; are not supported.  So, if the file is missing, issue an error
+         ;; message.
+         (if (null term)
+             (if (equal edt-term "pc")
+                 (error "Unable to find EDT terminal specific file edt-pc.el")
+               (edt-load-keys nil))
+           (setq edt-term term))))
+    (edt-load-keys nil))
+  ;; Make highlighting of selected text work properly for EDT commands.
+  (if edt-gnu-emacs19-p
+      (progn
+       (setq edt-orig-transient-mark-mode transient-mark-mode)
+       (add-hook 'activate-mark-hook
+                 (function
+                  (lambda ()
+                    (edt-select-mode t))))
+       (add-hook 'deactivate-mark-hook
+                 (function
+                  (lambda ()
+                    (edt-select-mode nil)))))
+    (progn
+      (add-hook 'zmacs-activate-region-hook
+               (function
+                (lambda ()
+                  (edt-select-mode t))))
+      (add-hook 'zmacs-deactivate-region-hook
+               (function
+                (lambda ()
+                  (edt-select-mode nil))))))
+  ;;  Load user's EDT custom key bindings file, if it exists.
+  ;;  Otherwise, use the default bindings.
+  (if (load "edt-user" t t)
+      (edt-user-emulation-setup)
+      (edt-default-emulation-setup)))
+
+(defun edt-emulation-off()
+  "Select original global key bindings, disabling EDT Emulation."
+  (interactive)
+  (use-global-map global-map)
+  (if (not edt-keep-current-page-delimiter)
+      (setq page-delimiter edt-orig-page-delimiter))
+  (setq edt-direction-string "")
+  (setq edt-select-mode-current nil)
+  (edt-reset)
+  (force-mode-line-update t)
+  (if edt-gnu-emacs19-p
+    (setq transient-mark-mode edt-orig-transient-mark-mode))
+  (message "Original key bindings restored; EDT Emulation disabled"))
+
+(defun edt-default-emulation-setup (&optional user-setup)
+  "Setup emulation of DEC's EDT editor.
+Optional argument USER-SETUP non-nil means  called from function
+`edt-user-emulation-setup'."
+  ;; Setup default EDT global map by copying global map bindings.
+  ;; This preserves ESC and C-x prefix bindings and other bindings we
+  ;; wish to retain in EDT emulation mode keymaps.  It also permits
+  ;; customization of these bindings in the EDT global maps without
+  ;; disturbing the original bindings in global-map.
+  (fset 'edt-default-ESC-prefix (copy-keymap 'ESC-prefix))
+  (setq edt-default-global-map (copy-keymap (current-global-map)))
+  (if edt-gnu-emacs19-p
+      (define-key edt-default-global-map "\e" 'edt-default-ESC-prefix)
+    (define-key edt-default-global-map [escape] 'edt-default-ESC-prefix))
+  (define-prefix-command 'edt-default-gold-map)
+  (edt-setup-default-bindings)
+  ;; If terminal has additional function keys, the terminal-specific
+  ;; initialization file can assign bindings to them via the optional
+  ;; function edt-setup-extra-default-bindings.
+  (if (fboundp 'edt-setup-extra-default-bindings)
+      (edt-setup-extra-default-bindings))
+  ;; Variable needed by edt-learn.
+  (setq edt-learn-macro-count 0)
+  ;; Display EDT text selection active within the mode line
+  (or (assq 'edt-select-mode minor-mode-alist)
+      (setq minor-mode-alist
+           (cons '(edt-select-mode edt-select-mode) minor-mode-alist)))
+  ;; Display EDT direction of motion within the mode line
+  (or (assq 'edt-direction-string minor-mode-alist)
+      (setq minor-mode-alist
+           (cons
+            '(edt-direction-string edt-direction-string) minor-mode-alist)))
+  (if user-setup
+      (progn
+        (setq edt-user-map-configured t)
+        (fset 'edt-emulation-on (symbol-function 'edt-select-user-global-map)))
+    (progn
+      (fset 'edt-emulation-on (symbol-function 'edt-select-default-global-map))
+      (edt-select-default-global-map))))
+
+(defun edt-user-emulation-setup ()
+  "Setup user custom emulation of DEC's EDT editor."
+  ;; Initialize EDT default bindings.
+  (edt-default-emulation-setup t)
+  ;; Setup user EDT global map by copying default EDT global map bindings.
+  (fset 'edt-user-ESC-prefix (copy-keymap 'edt-default-ESC-prefix))
+  (setq edt-user-global-map (copy-keymap edt-default-global-map))
+  (if edt-gnu-emacs19-p
+      (define-key edt-user-global-map "\e" 'edt-user-ESC-prefix)
+    (define-key edt-user-global-map [escape] 'edt-user-ESC-prefix))
+  ;; If terminal has additional function keys, the user's initialization
+  ;; file can assign bindings to them via the optional
+  ;; function edt-setup-extra-default-bindings.
+  (define-prefix-command 'edt-user-gold-map)
+  (fset 'edt-user-gold-map (copy-keymap 'edt-default-gold-map))
+  (edt-setup-user-bindings)
+  (edt-select-user-global-map))
+
+(defun edt-select-default-global-map()
+  "Select default EDT emulation key bindings."
+  (interactive)
+  (if edt-gnu-emacs19-p
+    (transient-mark-mode 1))
+  (use-global-map edt-default-global-map)
+  (if (not edt-keep-current-page-delimiter)
+      (progn
+        (setq edt-orig-page-delimiter page-delimiter)
+        (setq page-delimiter "\f")))
+  (setq edt-default-map-active t)
+  (edt-advance)
+  (setq edt-select-mode-current 'edt-select-mode-string)
+  (edt-reset)
+  (message "Default EDT keymap active"))
+
+(defun edt-select-user-global-map()
+  "Select user EDT emulation custom key bindings."
+  (interactive)
+  (if edt-user-map-configured
+      (progn
+       (if edt-gnu-emacs19-p
+           (transient-mark-mode 1))
+        (use-global-map edt-user-global-map)
+        (if (not edt-keep-current-page-delimiter)
+            (progn
+              (setq edt-orig-page-delimiter page-delimiter)
+              (setq page-delimiter "\f")))
+        (setq edt-default-map-active nil)
+        (edt-advance)
+       (setq edt-select-mode-current 'edt-select-mode-string)
+        (edt-reset)
+        (message "User EDT custom keymap active"))
+    (error "User EDT custom keymap NOT configured!")))
+
+(defun edt-switch-global-maps ()
+  "Toggle between default EDT keymap and user EDT keymap."
+  (interactive)
+  (if edt-default-map-active
+      (edt-select-user-global-map)
+    (edt-select-default-global-map)))
+
+;;
+;;  Functions used to set up DEFAULT bindings to EDT emulation functions.
+;;
+
+(defun edt-bind-function-key-default (function-key binding gold-binding)
+  "Binds LK-201 function keys to default bindings in the EDT Emulator.
+Argument FUNCTION-KEY is the name of the function key or keypad function key.
+Argument BINDING is the Emacs function to be bound to <KEY>.
+Argument GOLD-BINDING is the Emacs function to be bound to GOLD <KEY>."
+  (let ((key (cdr (assoc function-key *EDT-keys*))))
+    (if (and key (not (equal key "")))
+       (progn
+         (define-key edt-default-global-map key binding)
+         (define-key 'edt-default-gold-map key gold-binding)))))
+
+(defun edt-bind-key-default (key binding)
+  "Bind key sequences to default bindings in the EDT Emulator.
+Argument KEY is the name of a standard key or a function key.
+Argument BINDING is the Emacs function to be bound to <KEY>."
+  (define-key edt-default-global-map key binding))
+
+(defun edt-bind-gold-key-default (key gold-binding)
+  "Binds <GOLD> key sequences to default bindings in the EDT Emulator.
+Argument KEY is the name of a standard key or a function key.
+Argument GOLD-BINDING is the Emacs function to be bound to GOLD <KEY>."
+  (define-key 'edt-default-gold-map key gold-binding))
+
+;;
+;;  Functions used to set up USER CUSTOM bindings to EDT emulation functions.
+;;
+(defun edt-bind-function-key (function-key binding gold-binding)
+  "Binds LK-201 function keys to custom bindings in the EDT Emulator.
+Argument FUNCTION-KEY is the name of the function key or keypad function key.
+Argument BINDING is the Emacs function to be bound to <KEY>.
+Argument GOLD-BINDING is the Emacs function to be bound to GOLD <KEY>."
+  (let ((key (cdr (assoc function-key *EDT-keys*))))
+    (if (and key (not (equal key "")))
+       (progn
+         (define-key edt-user-global-map key binding)
+         (define-key 'edt-user-gold-map key gold-binding)))))
+
+(defun edt-bind-key (key binding)
+  "Bind standard key sequences to custom bindings in the EDT Emulator.
+Argument KEY is the name of a key.  It can be a standard key or a function key.
+Argument BINDING is the Emacs function to be bound to <KEY>."
+  (define-key edt-user-global-map key binding))
+
+;;  For backward compatibility to existing edt-user.el files.
+(fset 'edt-bind-standard-key (symbol-function 'edt-bind-key))
+
+(defun edt-bind-gold-key (key gold-binding)
+  "Binds <GOLD> standard key sequences to custom bindings in the EDT Emulator.
+Argument KEY is the name of a standard key or a function key.
+Argument GOLD-BINDING is the Emacs function to be bound to GOLD <KEY>."
+  (define-key 'edt-user-gold-map key gold-binding))
+
+(defun edt-setup-default-bindings ()
+  "Assigns default EDT Emulation keyboard bindings."
+
+  ;; Function Key Bindings:  Regular and GOLD.
+
+  ;; VT100/VT200/VT300 PF1 (GOLD), PF2, PF3, PF4 Keys
+  (edt-bind-function-key-default "PF1"
+       'edt-default-gold-map 'edt-mark-section-wisely)
+  (edt-bind-function-key-default "PF2"
+       'edt-electric-keypad-help 'describe-function)
+  (edt-bind-function-key-default "PF3" 'edt-find-next 'edt-find)
+  (edt-bind-function-key-default "PF4" 'edt-delete-line 'edt-undelete-line)
+
+  ;; VT100/VT200/VT300 Arrow Keys
+  (edt-bind-function-key-default "UP" 'edt-previous-line 'edt-window-top)
+  (edt-bind-function-key-default "DOWN" 'edt-next-line 'edt-window-bottom)
+  (edt-bind-function-key-default "LEFT" 'backward-char 'edt-sentence-backward)
+  (edt-bind-function-key-default "RIGHT" 'forward-char 'edt-sentence-forward)
+
+  ;; VT100/VT200/VT300 Keypad Keys
+  (edt-bind-function-key-default "KP0" 'edt-line 'open-line)
+  (edt-bind-function-key-default "KP1" 'edt-word 'edt-change-case)
+  (edt-bind-function-key-default "KP2"
+       'edt-end-of-line 'edt-delete-to-end-of-line)
+  (edt-bind-function-key-default "KP3" 'edt-character 'quoted-insert)
+  (edt-bind-function-key-default "KP4" 'edt-advance 'edt-bottom)
+  (edt-bind-function-key-default "KP5" 'edt-backup 'edt-top)
+  (edt-bind-function-key-default "KP6" 'edt-cut 'yank)
+  (edt-bind-function-key-default "KP7" 'edt-page 'execute-extended-command)
+  (edt-bind-function-key-default "KP8" 'edt-sect 'edt-fill-region)
+  (edt-bind-function-key-default "KP9" 'edt-append 'edt-replace)
+  (edt-bind-function-key-default "KP-" 'edt-delete-word 'edt-undelete-word)
+  (edt-bind-function-key-default "KP,"
+       'edt-delete-character 'edt-undelete-character)
+  (edt-bind-function-key-default "KPP" 'edt-select 'edt-reset)
+  (edt-bind-function-key-default "KPE" 'other-window 'edt-substitute)
+
+  ;; VT200/VT300 Function Keys
+  ;; (F1 through F5, on the VT220, are not programmable, so we skip
+  ;; making default bindings to those keys.
+  (edt-bind-function-key-default "FIND" 'edt-find-next 'edt-find)
+  (edt-bind-function-key-default "INSERT" 'yank 'edt-key-not-assigned)
+  (edt-bind-function-key-default "REMOVE" 'edt-cut 'edt-copy)
+  (edt-bind-function-key-default "SELECT"
+       'edt-toggle-select 'edt-key-not-assigned)
+  (edt-bind-function-key-default "NEXT"
+       'edt-sect-forward 'edt-key-not-assigned)
+  (edt-bind-function-key-default "PREVIOUS"
+       'edt-sect-backward 'edt-key-not-assigned)
+  (edt-bind-function-key-default "F6"
+       'edt-key-not-assigned 'edt-key-not-assigned)
+  (edt-bind-function-key-default "F7"
+       'edt-copy-rectangle 'edt-key-not-assigned)
+  (edt-bind-function-key-default "F8"
+       'edt-cut-rectangle-overstrike-mode 'edt-paste-rectangle-overstrike-mode)
+  (edt-bind-function-key-default "F9"
+       'edt-cut-rectangle-insert-mode 'edt-paste-rectangle-insert-mode)
+  (edt-bind-function-key-default "F10" 'edt-cut-rectangle 'edt-paste-rectangle)
+  ;; Under X, the F11 key can be bound.  If using a VT-200 or higher terminal,
+  ;; the default emacs terminal support causes the VT F11 key to seem as if it
+  ;; is an ESC key when in emacs.
+  (edt-bind-function-key-default "F11"
+       'edt-key-not-assigned 'edt-key-not-assigned)
+  (edt-bind-function-key-default "F12"
+       'edt-beginning-of-line 'delete-other-windows) ;BS
+  (edt-bind-function-key-default "F13"
+       'edt-delete-to-beginning-of-word 'edt-key-not-assigned) ;LF
+  (edt-bind-function-key-default "F14"
+       'edt-key-not-assigned 'edt-key-not-assigned)
+  (edt-bind-function-key-default "HELP"
+       'edt-electric-keypad-help 'edt-key-not-assigned)
+  (edt-bind-function-key-default "DO"
+       'execute-extended-command 'edt-key-not-assigned)
+  (edt-bind-function-key-default "F17"
+       'edt-key-not-assigned 'edt-key-not-assigned)
+  (edt-bind-function-key-default "F18"
+       'edt-key-not-assigned 'edt-key-not-assigned)
+  (edt-bind-function-key-default "F19"
+       'edt-key-not-assigned 'edt-key-not-assigned)
+  (edt-bind-function-key-default "F20"
+       'edt-key-not-assigned 'edt-key-not-assigned)
+
+  ;; Control key bindings:  Regular and GOLD
+  ;;
+  ;; Standard EDT control key bindings conflict with standard Emacs
+  ;; control key bindings.  Normally, the standard Emacs control key
+  ;; bindings are left unchanged in the default EDT mode.  However, if
+  ;; the variable edt-use-EDT-control-key-bindings is set to true
+  ;; before invoking edt-emulation-on for the first time, then the
+  ;; standard EDT bindings (with some enhancements) as defined here are
+  ;; used, instead.
+  (if edt-use-EDT-control-key-bindings
+      (progn
+        (edt-bind-key-default "\C-a" 'edt-key-not-assigned)
+        (edt-bind-key-default "\C-b" 'edt-key-not-assigned)
+        ;; Leave binding of C-c to an Emacs prefix key.
+        (edt-bind-key-default "\C-d" 'edt-key-not-assigned)
+        (edt-bind-key-default "\C-e" 'edt-key-not-assigned)
+        (edt-bind-key-default "\C-f" 'edt-key-not-assigned)
+        ;; Leave binding of C-g to the Emacs keyboard-quit
+        (edt-bind-key-default "\C-h" 'edt-beginning-of-line)
+        (edt-bind-key-default "\C-i" 'edt-tab-insert)
+        (edt-bind-key-default "\C-j" 'edt-delete-to-beginning-of-word)
+        (edt-bind-key-default "\C-k" 'edt-define-key)
+        (edt-bind-gold-key-default  "\C-k" 'edt-restore-key)
+        (edt-bind-key-default "\C-l" 'edt-form-feed-insert)
+        ;; Leave binding of C-m to newline.
+        (edt-bind-key-default "\C-n" 'edt-set-screen-width-80)
+        (edt-bind-key-default "\C-o" 'edt-key-not-assigned)
+        (edt-bind-key-default "\C-p" 'edt-key-not-assigned)
+        (edt-bind-key-default "\C-q" 'edt-key-not-assigned)
+        ;; Leave binding of C-r to isearch-backward.
+        ;; Leave binding of C-s to isearch-forward.
+        (edt-bind-key-default "\C-t" 'edt-display-the-time)
+        (edt-bind-key-default "\C-u" 'edt-delete-to-beginning-of-line)
+        (edt-bind-key-default "\C-v" 'redraw-display)
+        (edt-bind-key-default "\C-w" 'edt-set-screen-width-132)
+        ;; Leave binding of C-x as original prefix key.
+        (edt-bind-key-default "\C-y" 'edt-key-not-assigned)
+        ;; Leave binding of C-z to suspend-emacs.
+        )
+      )
+
+  ;; GOLD bindings for a few keys.
+  (edt-bind-gold-key-default  "\C-g" 'keyboard-quit); Just in case.
+  (edt-bind-gold-key-default  "\C-h" 'help-for-help); Just in case.
+  (edt-bind-gold-key-default  [f1] 'help-for-help)
+  (edt-bind-gold-key-default  [help] 'help-for-help)
+  (edt-bind-gold-key-default  "\C-\\" 'split-window-vertically)
+
+  ;; GOLD bindings for regular keys.
+  (edt-bind-gold-key-default "a" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "A" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "b" 'buffer-menu)
+  (edt-bind-gold-key-default "B" 'buffer-menu)
+  (edt-bind-gold-key-default "c" 'compile)
+  (edt-bind-gold-key-default "C" 'compile)
+  (edt-bind-gold-key-default "d" 'delete-window)
+  (edt-bind-gold-key-default "D" 'delete-window)
+  (edt-bind-gold-key-default "e" 'edt-exit)
+  (edt-bind-gold-key-default "E" 'edt-exit)
+  (edt-bind-gold-key-default "f" 'find-file)
+  (edt-bind-gold-key-default "F" 'find-file)
+  (edt-bind-gold-key-default "g" 'find-file-other-window)
+  (edt-bind-gold-key-default "G" 'find-file-other-window)
+  (edt-bind-gold-key-default "h" 'edt-electric-keypad-help)
+  (edt-bind-gold-key-default "H" 'edt-electric-keypad-help)
+  (edt-bind-gold-key-default "i" 'insert-file)
+  (edt-bind-gold-key-default "I" 'insert-file)
+  (edt-bind-gold-key-default "j" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "J" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "k" 'edt-toggle-capitalization-of-word)
+  (edt-bind-gold-key-default "K" 'edt-toggle-capitalization-of-word)
+  (edt-bind-gold-key-default "l" 'edt-lowercase)
+  (edt-bind-gold-key-default "L" 'edt-lowercase)
+  (edt-bind-gold-key-default "m" 'save-some-buffers)
+  (edt-bind-gold-key-default "M" 'save-some-buffers)
+  (edt-bind-gold-key-default "n" 'next-error)
+  (edt-bind-gold-key-default "N" 'next-error)
+  (edt-bind-gold-key-default "o" 'switch-to-buffer-other-window)
+  (edt-bind-gold-key-default "O" 'switch-to-buffer-other-window)
+  (edt-bind-gold-key-default "p" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "P" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "q" 'edt-quit)
+  (edt-bind-gold-key-default "Q" 'edt-quit)
+  (edt-bind-gold-key-default "r" 'revert-buffer)
+  (edt-bind-gold-key-default "R" 'revert-buffer)
+  (edt-bind-gold-key-default "s" 'save-buffer)
+  (edt-bind-gold-key-default "S" 'save-buffer)
+  (edt-bind-gold-key-default "t" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "T" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "u" 'edt-uppercase)
+  (edt-bind-gold-key-default "U" 'edt-uppercase)
+  (edt-bind-gold-key-default "v" 'find-file-other-window)
+  (edt-bind-gold-key-default "V" 'find-file-other-window)
+  (edt-bind-gold-key-default "w" 'write-file)
+  (edt-bind-gold-key-default "W" 'write-file)
+  (edt-bind-gold-key-default "x" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "X" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "y" 'edt-emulation-off)
+  (edt-bind-gold-key-default "Y" 'edt-emulation-off)
+  (edt-bind-gold-key-default "z" 'edt-switch-global-maps)
+  (edt-bind-gold-key-default "Z" 'edt-switch-global-maps)
+  (edt-bind-gold-key-default "1" 'delete-other-windows)
+  (edt-bind-gold-key-default "!" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "2" 'edt-split-window)
+  (edt-bind-gold-key-default "@" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "3" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "#" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "4" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "$" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "5" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "%" 'edt-goto-percentage)
+  (edt-bind-gold-key-default "6" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "^" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "7" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "&" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "8" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "*" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "9" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "(" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "0" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default ")" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default " " 'undo)
+  (edt-bind-gold-key-default "," 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "<" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "." 'edt-key-not-assigned)
+  (edt-bind-gold-key-default ">" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "/" 'query-replace)
+  (edt-bind-gold-key-default "?" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "\\" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "|" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default ";" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default ":" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "'" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "\"" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "-" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "_" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "=" 'goto-line)
+  (edt-bind-gold-key-default "+" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "[" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "{" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "]" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "}" 'edt-key-not-assigned)
+  (edt-bind-gold-key-default "`" 'what-line)
+  (edt-bind-gold-key-default "~" 'edt-key-not-assigned)
+)
+\f
+;;;
+;;; DEFAULT EDT KEYPAD HELP
+;;;
+
+;;;
+;;; Upper case commands in the keypad diagram below indicate that the
+;;; emulation should look and feel very much like EDT.  Lower case
+;;; commands are enhancements and/or additions to the EDT keypad
+;;; commands or are native Emacs commands.
+;;;
+
+(defun edt-keypad-help ()
+  "DEFAULT EDT Keypad Active.
+
+   F7: Copy Rectangle             +----------+----------+----------+----------+
+   F8: Cut Rect Overstrike        |Prev Line |Next Line |Bkwd Char |Frwd Char |
+ G-F8: Paste Rect Overstrike      |   (UP)   |  (DOWN)  |  (LEFT)  | (RIGHT)  |
+   F9: Cut Rect Insert            |Window Top|Window Bot|Bkwd Sent |Frwd Sent |
+ G-F9: Paste Rect Insert          +----------+----------+----------+----------+
+  F10: Cut Rectangle
+G-F10: Paste Rectangle
+  F11: ESC
+  F12: Begining of Line           +----------+----------+----------+----------+
+G-F12: Delete Other Windows       |   GOLD   |   HELP   |  FNDNXT  |  DEL L   |
+  F13: Delete to Begin of Word    |   (PF1)  |   (PF2)  |   (PF3)  |  (PF4)   |
+ HELP: Keypad Help                |Mark Wisel|Desc Funct|   FIND   |  UND L   |
+G-HELP: Emacs Help                +----------+----------+----------+----------+
+   DO: Execute extended command   |   PAGE   |   SECT   |  APPEND  |  DEL W   |
+  C-g: Keyboard Quit              |    (7)   |    (8)   |    (9)   |   (-)    |
+G-C-g: Keyboard Quit              |Ex Ext Cmd|Fill Regio| REPLACE  |  UND W   |
+  C-h: Beginning of Line          +----------+----------+----------+----------+
+G-C-h: Emacs Help                 |  ADVANCE |  BACKUP  |   CUT    |  DEL C   |
+  C-i: Tab Insert                 |    (4)   |    (5)   |    (6)   |   (,)    |
+  C-j: Delete to Begin of Word    |   BOTTOM |    TOP   |   Yank   |  UND C   |
+  C-k: Define Key                 +----------+----------+----------+----------+
+G-C-k: Restore Key                |   WORD   |    EOL   |   CHAR   |   Next   |
+  C-l: Form Feed Insert           |    (1)   |    (2)   |    (3)   |  Window  |
+  C-n: Set Screen Width 80        | CHNGCASE |  DEL EOL |Quoted Ins|          !
+  C-r: Isearch Backward           +---------------------+----------+  (ENTER) |
+  C-s: Isearch Forward            |         LINE        |  SELECT  |          !
+  C-t: Display the Time           |         (0)         |    (.)   |   SUBS   |
+  C-u: Delete to Begin of Line    |      Open Line      |   RESET  |          |
+  C-v: Redraw Display             +---------------------+----------+----------+
+  C-w: Set Screen Width 132
+  C-z: Suspend Emacs                    +----------+----------+----------+
+G-C-\\: Split Window                     |  FNDNXT  |   Yank   |   CUT    |
+                                        |  (FIND)  | (INSERT) | (REMOVE) |
+  G-b: Buffer Menu                      |   FIND   |          |   COPY   |
+  G-c: Compile                          +----------+----------+----------+
+  G-d: Delete Window                    |SELECT/RES|SECT BACKW|SECT FORWA|
+  G-e: Exit                             | (SELECT) |(PREVIOUS)|  (NEXT)  |
+  G-f: Find File                        |          |          |          |
+  G-g: Find File Other Window           +----------+----------+----------+
+  G-h: Keypad Help
+  G-i: Insert File
+  G-k: Toggle Capitalization Word
+  G-l: Downcase Region
+  G-m: Save Some Buffers
+  G-n: Next Error
+  G-o: Switch to Next Window
+  G-q: Quit
+  G-r: Revert File
+  G-s: Save Buffer
+  G-u: Upcase Region
+  G-v: Find File Other Window
+  G-w: Write file
+  G-y: EDT Emulation OFF
+  G-z: Switch to User EDT Key Bindings
+  G-1: Delete Other Windows
+  G-2: Split Window
+  G-%: Go to Percentage
+  G- : Undo  (GOLD Spacebar)
+  G-=: Go to Line
+  G-`: What line
+  G-/: Query-Replace"
+
+  (interactive)
+  (describe-function 'edt-keypad-help))
+
+(defun edt-electric-helpify (fun)
+  (let ((name "*Help*"))
+    (if (save-window-excursion
+          (let* ((p (symbol-function 'print-help-return-message))
+                 (b (get-buffer name))
+                 (m (buffer-modified-p b)))
+            (and b (not (get-buffer-window b))
+                 (setq b nil))
+            (unwind-protect
+                (progn
+                  (message "%s..." (capitalize (symbol-name fun)))
+                  (and b
+                       (save-excursion
+                         (set-buffer b)
+                         (set-buffer-modified-p t)))
+                  (fset 'print-help-return-message 'ignore)
+                  (call-interactively fun)
+                  (and (get-buffer name)
+                       (get-buffer-window (get-buffer name))
+                       (or (not b)
+                           (not (eq b (get-buffer name)))
+                           (not (buffer-modified-p b)))))
+              (fset 'print-help-return-message p)
+              (and b (buffer-name b)
+                   (save-excursion
+                     (set-buffer b)
+                     (set-buffer-modified-p m))))))
+        (with-electric-help 'delete-other-windows name t))))
+
+(defun edt-electric-keypad-help ()
+  "Display default EDT bindings."
+  (interactive)
+  (edt-electric-helpify 'edt-keypad-help))
+
+(defun edt-electric-user-keypad-help ()
+  "Display user custom EDT bindings."
+  (interactive)
+  (edt-electric-helpify 'edt-user-keypad-help))
+
+;;;
+;;; EDT emulation screen width commands.
+;;;
+;; Some terminals require modification of terminal attributes when
+;; changing the number of columns displayed, hence the fboundp tests
+;; below.  These functions are defined in the corresponding terminal
+;; specific file, if needed.
+
+(defun edt-set-screen-width-80 ()
+  "Set screen width to 80 columns."
+  (interactive)
+  (if (fboundp 'edt-set-term-width-80)
+      (edt-set-term-width-80))
+  (set-frame-width nil 80)
+  (message "Terminal width 80"))
+
+(defun edt-set-screen-width-132 ()
+  "Set screen width to 132 columns."
+  (interactive)
+  (if (fboundp 'edt-set-term-width-132)
+      (edt-set-term-width-132))
+  (set-frame-width nil 132)
+  (message "Terminal width 132"))
+
+(provide 'edt)
+
+;;; edt.el ends here