Commits

steve  committed 91580ce

Created

  • Participants
  • Tags xemacs

Comments (0)

Files changed (8)

+1998-01-03  SL Baur  <steve@altair.xemacs.org>
+
+	* Makefile: Update to newer package interface.
+
+1997-12-21  SL Baur  <steve@altair.xemacs.org>
+
+	* Makefile: Created.
+
+# Makefile for TPU/EDT lisp code
+
+# This file is part of XEmacs.
+
+# XEmacs 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.
+
+# XEmacs 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 XEmacs; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+VERSION = 1.03
+PACKAGE = tpu
+PKG_TYPE = regular
+REQUIRES = 
+CATEGORY = wp
+
+ELCS = tpu-doc.elc tpu-edt.elc tpu-extras.elc tpu-mapper.elc
+
+include ../../XEmacs.rules
+
+all:: $(ELCS) auto-autoloads.elc
+
+srckit: srckit-std
+
+binkit: binkit-sourceonly

File package-info.in

+(tpu
+  (version VERSION
+   description "DEC EDIT/TPU support."
+   filename FILENAME
+   md5sum MD5SUM
+   size SIZE
+   provides (tpu)
+   requires (REQUIRES)
+   type regular
+))
+;;; tpu-doc.el --- Documentation for TPU-edt
+
+;; Copyright (C) 1993 Free Software Foundation, Inc.
+
+;; Author: Rob Riepel <riepel@networking.stanford.edu>
+;; Maintainer: Rob Riepel <riepel@networking.stanford.edu>
+;; Keywords: emulations
+
+;; This file is part of XEmacs.
+
+;; XEmacs 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.
+
+;; XEmacs 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 XEmacs; see the file COPYING.  If not, write to the Free
+;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+(defconst tpu-doc-revision "!Revision: 1.6 !"
+  "TPU-edt documentation revision number.")
+
+
+;; This is documentation for the TPU-edt editor for GNU emacs.  Major
+;; sections of this document are separated with lines that begin with
+;; ";; %% <topic>", where <topic> is what is discussed in that section.
+
+
+;; %% Contents
+
+;;  % Introduction
+;;  % Terminal Support
+;;  % X-windows Support
+;;  % Differences Between TPU-edt and the Real Thing
+;;  % Starting TPU-edt
+;;  % TPU-edt Default Editing Keypad, Control and Gold Key Bindings
+;;  % Optional TPU-edt Extensions
+;;  % Customizing TPU-edt using the Emacs Initialization File
+;;  % Compiling TPU-edt
+;;  % Regular expressions in TPU-edt
+;;  % Etcetera
+
+
+;; %% Introduction
+
+;;    TPU-edt is based on tpu.el by Jeff Kowalski.  TPU-edt endeavors
+;;    to be even more like TPU's EDT emulation than the original tpu.el.
+;;    Considerable effort has been expended to that end.  Still, emacs
+;;    is emacs and there are differences between TPU-edt and the real
+;;    thing.  Please read the "Differences Between TPU-edt and the Real
+;;    Thing" and "Starting TPU-edt" sections before running TPU-edt.
+
+
+;; %% Terminal Support
+
+;;    TPU-edt, like it's VMS cousin, works on VT-series terminals with
+;;    DEC style keyboards.  VT terminal emulators, including xterm with
+;;    the appropriate key translations, work just fine too.
+
+
+;; %% X-windows Support
+
+;;    Starting with version 19 of emacs, TPU-edt works with X-windows.
+;;    This is accomplished through a TPU-edt X keymap.  The emacs lisp
+;;    program tpu-mapper.el creates this map and stores it in a file.
+;;    Tpu-mapper will be run automatically the first time you invoke
+;;    the X-windows version of emacs, or you can run it by hand.  See
+;;    the commentary in tpu-mapper.el for details.
+
+
+;; %% Differences Between TPU-edt and the Real Thing (not Coke (r))
+
+;;    Emacs (version 18.58) doesn't support text highlighting, so selected
+;;    regions are not shown in inverse video.  Emacs uses the concept of
+;;    "the mark".  The mark is set at one end of a selected region; the
+;;    cursor is at the other.  The letter "M" appears in the mode line
+;;    when the mark is set.  The native emacs command ^X^X (Control-X
+;;    twice) exchanges the cursor with the mark; this provides a handy
+;;    way to find the location of the mark.
+
+;;    In TPU the cursor can be either bound or free.  Bound means the
+;;    cursor cannot wander outside the text of the file being edited.
+;;    Free means the arrow keys can move the cursor past the ends of
+;;    lines.  Free is the default mode in TPU; bound is the only mode
+;;    in EDT.  Bound is the only mode in the base version of TPU-edt;
+;;    optional extensions add an approximation of free mode.
+
+;;    Like TPU, emacs uses multiple buffers.  Some buffers are used to
+;;    hold files you are editing; other "internal" buffers are used for
+;;    emacs' own purposes (like showing you help).  Here are some commands
+;;    for dealing with buffers.
+
+;;	 Gold-B   moves to next buffer, including internal buffers
+;;	 Gold-N   moves to next buffer containing a file
+;;	 Gold-M   brings up a buffer menu (like TPU "show buffers")
+
+;;    Emacs is very fond of throwing up new windows.  Dealing with all
+;;    these windows can be a little confusing at first, so here are a few
+;;    commands to that may help:
+
+;;       Gold-Next_Scr  moves to the next window on the screen
+;;       Gold-Prev_Scr  moves to the previous window on the screen
+;;       Gold-TAB       also moves to the next window on the screen
+
+;;	 Control-x 1    deletes all but the current window
+;;	 Control-x 0    deletes the current window
+
+;;    Note that the buffers associated with deleted windows still exist!
+
+;;    Like TPU, TPU-edt has a "command" function, invoked with Gold-KP7 or
+;;    Do.  Most of the commands available are emacs commands.  Some TPU
+;;    commands are available, they are: replace, exit, quit, include, and
+;;    Get (unfortunately, "get" is an internal emacs function, so we are
+;;    stuck with "Get" - to make life easier, Get is available as Gold-g).
+
+;;    Support for recall of commands, file names, and search strings was
+;;    added to emacs in version 19.  For version 18 of emacs, optional
+;;    extensions are available to add this recall capability (see "Optional
+;;    TPU-edt Extensions" below).  The history of strings recalled in both
+;;    versions of emacs differs slightly from TPU/edt, but it is still very
+;;    convenient.
+
+;;    Help is available!  The traditional help keys (Help and PF2) display
+;;    a three page help file showing the default keypad layout, control key
+;;    functions, and Gold key functions.  Pressing any key inside of help
+;;    splits the screen and prints a description of the function of the
+;;    pressed key.  Gold-PF2 invokes the native emacs help, with it's
+;;    zillions of options.  Gold-Help shows all the current key bindings.
+
+;;    Thanks to emacs, TPU-edt has some extensions that may make your life
+;;    easier, or at least more interesting.  For example, Gold-r toggles
+;;    TPU-edt rectangular mode.  In rectangular mode, Remove and Insert work
+;;    on rectangles.  Likewise, Gold-* toggles TPU-edt regular expression
+;;    mode.  In regular expression mode Find, Find Next, and the line-mode
+;;    replace command work with regular expressions.  [A regular expression
+;;    is a pattern that denotes a set of strings; like VMS wildcards.]
+
+;;    Emacs also gives TPU-edt the undo and occur functions.  Undo does
+;;    what it says; it undoes the last change.  Multiple undos in a row
+;;    undo multiple changes.  For your convenience, undo is available on
+;;    Gold-u.  Occur shows all the lines containing a specific string in
+;;    another window.  Moving to that window, and typing ^C^C (Control-C
+;;    twice) on a particular line moves you back to the original window
+;;    at that line.  Occur is on Gold-o.
+
+;;    Finally, as you edit, remember that all the power of emacs is at
+;;    your disposal.  It really is a fantastic tool.  You may even want to
+;;    take some time and read the emacs tutorial; perhaps not to learn the
+;;    native emacs key bindings, but to get a feel for all the things
+;;    emacs can do for you.  The emacs tutorial is available from the
+;;    emacs help function: "Gold-PF2 t"
+
+
+;; %% Starting TPU-edt
+
+;;    In order to use TPU-edt, the TPU-edt editor definitions, contained
+;;    in tpu-edt.el, need to be loaded when emacs is run.  This can be
+;;    done in a couple of ways.  The first is by explicitly requesting
+;;    loading of the TPU-edt emacs definition file on the command line:
+
+;;        prompt> emacs -l /path/to/definitions/tpu-edt.el
+
+;;    If TPU-edt is installed on your system, that is, if tpu-edt.el is in
+;;    a directory like /usr/local/emacs/lisp, along with dozens of other
+;;    .el files, you should be able to use the command:
+
+;;        prompt> emacs -l tpu-edt
+
+;;    If you like TPU-edt and want to use it all the time, you can load
+;;    the TPU-edt definitions using the emacs initialization file, .emacs.
+;;    Simply create a .emacs file in your home directory containing the
+;;    line:
+
+;;        (load "/path/to/definitions/tpu-edt")
+
+;;    or, if (as above) TPU-edt is installed on your system:
+
+;;        (load "tpu-edt")
+
+;;    Once TPU-edt has been loaded, you will be using an editor with the
+;;    interface shown in the next section (A section that is suitable for
+;;    cutting out of this document and pasting next to your terminal!).
+
+
+;; %% TPU-edt Default Editing Keypad, Control and Gold Key Bindings
+;;
+;;        _______________________    _______________________________
+;;       | HELP  |      Do       |  |       |       |       |       |
+;;       |KeyDefs|               |  |       |       |       |       |
+;;       |_______|_______________|  |_______|_______|_______|_______|
+;;        _______________________    _______________________________
+;;       | Find  |Insert |Remove |  | Gold  | HELP  |FndNxt | Del L |
+;;       |       |       |Sto Tex|  |  key  |E-Help | Find  |Undel L|
+;;       |_______|_______|_______|  |_______|_______|_______|_______|
+;;       |Select |Pre Scr|Nex Scr|  | Page  | Sect  |Append | Del W |
+;;       | Reset |Pre Win|Nex Win|  |  Do   | Fill  |Replace|Undel W|
+;;       |_______|_______|_______|  |_______|_______|_______|_______|
+;;               |Move up|          |Forward|Reverse|Remove | Del C |
+;;               |  Top  |          |Bottom |  Top  |Insert |Undel C|
+;;        _______|_______|_______   |_______|_______|_______|_______|
+;;       |Mov Lef|Mov Dow|Mov Rig|  | Word  |  EOL  | Char  |       |
+;;       |StaOfLi|Bottom |EndOfLi|  |ChngCas|Del EOL|SpecIns| Enter |
+;;       |_______|_______|_______|  |_______|_______|_______|       |
+;;                                  |     Line      |Select | Subs  |
+;;                                  |   Open Line   | Reset |       |
+;;                                  |_______________|_______|_______|
+;;     Control Characters
+;;
+;;    ^A  toggle insert and overwrite    ^L  insert page break
+;;    ^B  recall                         ^R  remember, re-center
+;;    ^E  end of line                    ^U  delete to beginning of line
+;;    ^G  cancel current operation       ^V  quote
+;;    ^H  beginning of line              ^W  refresh
+;;    ^J  delete previous word           ^Z  exit
+;;    ^K  learn                        ^X^X  exchange point and mark
+;;
+;;
+;;     Gold-<key> Functions
+;;     -----------------------------------------------------------------
+;;     W     Write - save current buffer
+;;     K     Kill buffer - abandon edits and delete buffer
+;;
+;;     E     Exit - save current buffer and ask about others
+;;     X     eXit - save all modified buffers and exit
+;;     Q     Quit - exit without saving anything
+;;
+;;     G     Get - load a file into a new edit buffer
+;;     I     Include - include a file in this buffer
+;;
+;;     B     next Buffer - display the next buffer (all buffers)
+;;     N     Next file buffer - display next buffer containing a file
+;;     M     buffer Menu - display a list of all buffers
+;;
+;;     U     Undo - undo the last edit
+;;     C     Recall - edit and possibly repeat previous commands
+;;
+;;     O     Occur - show following lines containing REGEXP
+;;     S     Search and substitute - line mode REPLACE command
+;;
+;;     ?     Spell check - check spelling in a region or entire buffer
+;;
+;;     R     Toggle Rectangular mode for remove and insert
+;;     *     Toggle regular expression mode for search and substitute
+;;
+;;     V     Show TPU-edt version
+;;     -----------------------------------------------------------------
+
+
+;; %% Optional TPU-edt Extensions
+
+;;    Several optional packages have been included in this distribution
+;;    of TPU-edt.  The following is a brief description of each package.
+;;    See the {package}.el file for more detailed information and usage
+;;    instructions.
+
+;;      tpu-extras  -  TPU/edt scroll margins and free cursor mode.
+;;      tpu-recall  -  String, file name, and command history.
+;;      vt-control  -  VTxxx terminal width and keypad controls.
+
+;;    Packages are normally loaded from the emacs initialization file
+;;    (discussed below).  If a package is not installed in the emacs
+;;    lisp directory, it can be loaded by specifying the complete path
+;;    to the package file.  However, it is preferable to modify the
+;;    emacs load-path variable to include the directory where packages
+;;    are stored.  This way, packages can be loaded by name, just as if
+;;    they were installed.  The first part of the sample .emacs file
+;;    below shows how to make such a modification.
+
+
+;; %% Customizing TPU-edt using the Emacs Initialization File
+
+;; .emacs - a sample emacs initialization file
+
+;; This is a sample emacs initialization file.  It shows how to invoke
+;; TPU-edt, and how to customize it.
+
+;; The load-path is where emacs looks for files to fulfill load requests.
+;; If TPU-edt is not installed in a standard emacs directory, the load-path
+;; should be updated to include the directory where the TPU-edt files are
+;; stored.  Modify and un-comment the following section if TPU-ed is not
+;; installed on your system - be sure to leave the double quotes!
+
+;; (setq load-path
+;;       (append (list (expand-file-name "/path/to/tpu-edt/files"))
+;;               load-path))
+
+;; Load TPU-edt
+(load "tpu-edt")
+
+;; Load the optional goodies - scroll margins, free cursor mode, command
+;; and string recall.  But don't complain if the file aren't available.
+(load "tpu-extras" t)
+(load "tpu-recall" t)
+
+;; Uncomment this line to set scroll margins 10% (top) and 15% (bottom).
+;(and (fboundp 'tpu-set-scroll-margins) (tpu-set-scroll-margins "10%" "15%"))
+
+;; Load the vtxxx terminal control functions, but don't complain if
+;; the file is not found.
+(load "vt-control" t)
+
+;; TPU-edt treats words like EDT; here's how to add word separators.
+;; Note that backslash (\) and double quote (") are quoted with '\'.
+(tpu-add-word-separators "]\\[-_,.\"=+()'/*#:!&;$")
+
+;; Emacs is happy to save files without a final newline; other Unix programs
+;; hate that!  This line will make sure that files end with newlines.
+(setq require-final-newline t)
+
+;; Emacs has the ability to automatically run code embedded in files
+;; you edit.  This line makes emacs ask if you want to run the code.
+(if tpu-emacs19-p (setq enable-local-variables "ask")
+  (setq inhibit-local-variables t))
+
+;; Emacs uses Control-s and Control-q.  Problems can occur when using emacs
+;; on terminals that use these codes for flow control (Xon/Xoff flow control).
+;; These lines disable emacs' use of these characters.
+(global-unset-key "\C-s")
+(global-unset-key "\C-q")
+
+;; top, bottom, bol, eol seem like a waste of Gold-arrow functions.  The
+;; following section re-maps up and down arrow keys to top and bottom of
+;; screen, and left and right arrow keys to pan left and right (pan-left,
+;; right moves the screen 16 characters left or right - try it, you'll
+;; like it!).
+
+;; Re-map the Gold-arrow functions
+(define-key GOLD-CSI-map "A" 'tpu-beginning-of-window)          ; up-arrow
+(define-key GOLD-CSI-map "B" 'tpu-end-of-window)                ; down-arrow
+(define-key GOLD-CSI-map "C" 'tpu-pan-right)                    ; right-arrow
+(define-key GOLD-CSI-map "D" 'tpu-pan-left)                     ; left-arrow
+(define-key GOLD-SS3-map "A" 'tpu-beginning-of-window)          ; up-arrow
+(define-key GOLD-SS3-map "B" 'tpu-end-of-window)                ; down-arrow
+(define-key GOLD-SS3-map "C" 'tpu-pan-right)                    ; right-arrow
+(define-key GOLD-SS3-map "D" 'tpu-pan-left)                     ; left-arrow
+
+;; Re-map the Gold-arrow functions for X-windows TPU-edt (emacs version 19)
+(cond
+ ((and tpu-emacs19-p window-system)
+  (define-key GOLD-map [up] 'tpu-beginning-of-window)           ; up-arrow
+  (define-key GOLD-map [down] 'tpu-end-of-window)               ; down-arrow
+  (define-key GOLD-map [right] 'tpu-pan-right)                  ; right-arrow
+  (define-key GOLD-map [left] 'tpu-pan-left)))                  ; left-arrow
+
+;; The emacs universal-argument function is very useful for native emacs
+;; commands.  This line maps universal-argument to Gold-PF1
+(define-key GOLD-SS3-map "P" 'universal-argument)               ; Gold-PF1
+
+;; Make KP7 move by paragraphs, instead of pages.
+(define-key SS3-map "w" 'tpu-paragraph)                         ; KP7
+
+;; TPU-edt assumes you have the ispell spelling checker;
+;; Un-comment this line if you don't.
+;(setq tpu-have-spell nil)
+
+;; Display the TPU-edt version.
+(tpu-version)
+
+;; End of .emacs - a sample emacs initialization file
+
+;;    After initialization with the .emacs file shown above, the editing
+;;    keys have been re-mapped to look like this:
+
+;;        _______________________    _______________________________
+;;       | HELP  |      Do       |  |       |       |       |       |
+;;       |KeyDefs|               |  |       |       |       |       |
+;;       |_______|_______________|  |_______|_______|_______|_______|
+;;        _______________________    _______________________________
+;;       | Find  |Insert |Remove |  | Gold  | HELP  |FndNxt | Del L |
+;;       |       |       |Sto Tex|  | U Arg |E-Help | Find  |Undel L|
+;;       |_______|_______|_______|  |_______|_______|_______|_______|
+;;       |Select |Pre Scr|Nex Scr|  |Paragra| Sect  |Append | Del W |
+;;       | Reset |Pre Win|Nex Win|  |  Do   | Fill  |Replace|Undel W|
+;;       |_______|_______|_______|  |_______|_______|_______|_______|
+;;               |Move up|          |Forward|Reverse|Remove | Del C |
+;;               |Tscreen|          |Bottom |  Top  |Insert |Undel C|
+;;        _______|_______|_______   |_______|_______|_______|_______|
+;;       |Mov Lef|Mov Dow|Mov Rig|  | Word  |  EOL  | Char  |       |
+;;       |PanLeft|Bscreen|PanRigh|  |ChngCas|Del EOL|SpecIns| Enter |
+;;       |_______|_______|_______|  |_______|_______|_______|       |
+;;                                  |     Line      |Select | Subs  |
+;;                                  |   Open Line   | Reset |       |
+;;                                  |_______________|_______|_______|
+
+;;    Astute emacs hackers will realize that on systems where TPU-edt is
+;;    installed, this documentation file can be loaded to produce the above
+;;    editing keypad layout.  In fact, to get all the changes in the sample
+;;    initialization file, you only need a one line initialization file:
+
+;;        (load "tpu-doc")
+
+;;    wow!
+
+
+;; %% Compiling TPU-edt
+
+;;    It is not necessary to compile (byte-compile in emacs parlance)
+;;    TPU-edt to use it.  However, byte-compiled code loads and runs
+;;    faster, and takes up less memory when loaded.  To byte compile
+;;    TPU-edt, use the following command.
+
+;;        emacs -batch -f batch-byte-compile tpu-edt.el
+
+;;    This will produce a file named tpu-edt.elc.  This new file can be
+;;    used in place of the original tpu-edt.el file.  In commands where
+;;    the file type is not specified, emacs always attempts to use the
+;;    byte-compiled version before resorting to the source.
+
+
+;; %% Regular expressions in TPU-edt
+
+;;    Gold-* toggles TPU-edt regular expression mode.  In regular expression
+;;    mode, find, find next, replace, and substitute accept emacs regular
+;;    expressions.  A complete list of emacs regular expressions can be
+;;    found using the emacs "info" command (it's somewhat like the VMS help
+;;    command).  Try the following sequence of commands:
+
+;;        DO info             <enter info mode>
+;;	  m regex             <select the "regular expression" topic>
+;;	  m directives        <select the "directives" topic>
+
+;;    Type "q" to quit out of info mode.
+
+;;    There is a problem in regular expression mode when searching for
+;;    empty strings, like beginning-of-line (^) and end-of-line ($).
+;;    When searching for these strings, find-next may find the current
+;;    string, instead of the next one.  This can cause global replace and
+;;    substitute commands to loop forever in the same location.  For this
+;;    reason, commands like
+
+;;        replace "^" "> "       <add "> " to beginning of line>
+;;	  replace "$" "00711"    <add "00711" to end of line>
+
+;;    may not work properly.
+
+;;    Commands like those above are very useful for adding text to the
+;;    beginning or end of lines.  They might work on a line-by-line basis,
+;;    but go into an infinite loop if the "all" response is specified.  If
+;;    the goal is to add a string to the beginning or end of a particular
+;;    set of lines TPU-edt provides functions to do this.
+
+;;        Gold-^  Add a string at BOL in region or buffer
+;;        Gold-$  Add a string at EOL in region or buffer
+
+;;    There is also a TPU-edt interface to the native emacs string
+;;    replacement commands.  Gold-/ invokes this command.  It accepts
+;;    regular expressions if TPU-edt is in regular expression mode.  Given
+;;    a repeat count, it will perform the replacement without prompting
+;;    for confirmation.
+
+;;    This command replaces empty strings correctly, however, it has its
+;;    drawbacks.  As a native emacs command, it has a different interface
+;;    than the emulated TPU commands.  Also, it works only in the forward
+;;    direction, regardless of the current TPU-edt direction.
+
+
+;; %% Etcetera
+
+;;    That's TPU-edt in a nutshell...
+
+;;    Please send any bug reports, feature requests, or cookies to the
+;;    author, Rob Riepel, at the address shown by the tpu-version command
+;;    (Gold-V).
+
+;;    Share and enjoy...  Rob Riepel  7/93
+
+;;; tpu-doc.el ends here
+;;; tpu-edt.el --- Emacs emulating TPU emulating EDT
+
+;; Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+;; Author: Rob Riepel <riepel@networking.stanford.edu>
+;; Maintainer: Rob Riepel <riepel@networking.stanford.edu>
+;; Version: 4.2
+;; Keywords: emulations
+
+;; This file is part of XEmacs.
+;; Modified for XEmacs by Kevin Oberman <oberman@es.net>
+
+;; XEmacs 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.
+
+;; XEmacs 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 XEmacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Synced up with FSF 19.34 and XEmacs 19.16
+
+;; TPU-edt is based on tpu.el by Jeff Kowalski and Bob Covey.
+
+;;; Commentary:
+
+;; %% TPU-edt -- Emacs emulating TPU emulating EDT
+
+;; %% Contents
+
+;;  % Introduction
+;;  % Differences Between TPU-edt and DEC TPU/edt
+;;  % Starting TPU-edt
+;;  % Customizing TPU-edt using the Emacs Initialization File
+;;  % Regular Expressions in TPU-edt
+
+
+;; %% Introduction
+
+;;    TPU-edt emulates the popular DEC VMS editor EDT (actually, it emulates
+;;    DEC TPU's EDT emulation, hence the name TPU-edt).  TPU-edt features the
+;;    following TPU/edt functionality:
+
+;;     .  EDT keypad
+;;     .  On-line help
+;;     .  Repeat counts
+;;     .  Scroll margins
+;;     .  Learn sequences
+;;     .  Free cursor mode
+;;     .  Rectangular cut and paste
+;;     .  Multiple windows and buffers
+;;     .  TPU line-mode REPLACE command
+;;     .  Wild card search and substitution
+;;     .  Configurable through an initialization file
+;;     .  History recall of search strings, file names, and commands
+
+;;    Please note that TPU-edt does NOT emulate TPU.  It emulates TPU's EDT
+;;    emulation.  Very few TPU line-mode commands are supported.
+
+;;    TPU-edt, like its VMS cousin, works on VT-series terminals with DEC
+;;    style keyboards.  VT terminal emulators, including xterm with the
+;;    appropriate key translations, work just fine too.
+
+;;    TPU-edt works with X-windows.  This is accomplished through a TPU-edt X
+;;    key map.  The TPU-edt module tpu-mapper creates this map and stores it
+;;    in a file.  Tpu-mapper will be run automatically the first time you
+;;    invoke the X-windows version of emacs, or you can run it by hand.  See
+;;    the commentary in tpu-mapper.el for details.
+
+
+;; %% Differences Between TPU-edt and DEC TPU/edt
+
+;;    In some cases, Emacs doesn't support text highlighting, so selected
+;;    regions are not shown in inverse video.  Emacs uses the concept of "the
+;;    mark".  The mark is set at one end of a selected region; the cursor is
+;;    at the other.  The letter "M" appears in the mode line when the mark is
+;;    set.  The native emacs command ^X^X (Control-X twice) exchanges the
+;;    cursor with the mark; this provides a handy way to find the location of
+;;    the mark.
+
+;;    In TPU the cursor can be either bound or free.  Bound means the cursor
+;;    cannot wander outside the text of the file being edited.  Free means
+;;    the arrow keys can move the cursor past the ends of lines.  Free is the
+;;    default mode in TPU; bound is the only mode in EDT.  Bound is the only
+;;    mode in the base version of TPU-edt; optional extensions add an
+;;    approximation of free mode, see the commentary in tpu-extras.el for
+;;    details.
+
+;;    Like TPU, emacs uses multiple buffers.  Some buffers are used to hold
+;;    files you are editing; other "internal" buffers are used for emacs' own
+;;    purposes (like showing you help).  Here are some commands for dealing
+;;    with buffers.
+
+;;       Gold-B   moves to next buffer, including internal buffers
+;;       Gold-N   moves to next buffer containing a file
+;;       Gold-M   brings up a buffer menu (like TPU "show buffers")
+
+;;    Emacs is very fond of throwing up new windows.  Dealing with all these
+;;    windows can be a little confusing at first, so here are a few commands
+;;    to that may help:
+
+;;       Gold-Next_Scr  moves to the next window on the screen
+;;       Gold-Prev_Scr  moves to the previous window on the screen
+;;       Gold-TAB       also moves to the next window on the screen
+
+;;       Control-x 1    deletes all but the current window
+;;       Control-x 0    deletes the current window
+
+;;    Note that the buffers associated with deleted windows still exist!
+
+;;    Like TPU, TPU-edt has a "command" function, invoked with Gold-KP7 or
+;;    Do.  Most of the commands available are emacs commands.  Some TPU
+;;    commands are available, they are: replace, exit, quit, include, and
+;;    Get (unfortunately, "get" is an internal emacs function, so we are
+;;    stuck with "Get" - to make life easier, Get is available as Gold-g).
+
+;;    TPU-edt supports the recall of commands, file names, and search
+;;    strings.  The history of strings recalled differs slightly from
+;;    TPU/edt, but it is still very convenient.
+
+;;    Help is available!  The traditional help keys (Help and PF2) display
+;;    a small help file showing the default keypad layout, control key
+;;    functions, and Gold key functions.  Pressing any key inside of help
+;;    splits the screen and prints a description of the function of the
+;;    pressed key.  Gold-PF2 invokes the native emacs help, with its
+;;    zillions of options.
+
+;;    Thanks to emacs, TPU-edt has some extensions that may make your life
+;;    easier, or at least more interesting.  For example, Gold-r toggles
+;;    TPU-edt rectangular mode.  In rectangular mode, Remove and Insert work
+;;    on rectangles.  Likewise, Gold-* toggles TPU-edt regular expression
+;;    mode.  In regular expression mode Find, Find Next, and the line-mode
+;;    replace command work with regular expressions.  [A regular expression
+;;    is a pattern that denotes a set of strings; like VMS wildcards.]
+
+;;    Emacs also gives TPU-edt the undo and occur functions.  Undo does
+;;    what it says; it undoes the last change.  Multiple undos in a row
+;;    undo multiple changes.  For your convenience, undo is available on
+;;    Gold-u.  Occur shows all the lines containing a specific string in
+;;    another window.  Moving to that window, and typing ^C^C (Control-C
+;;    twice) on a particular line moves you back to the original window
+;;    at that line.  Occur is on Gold-o.
+
+;;    Finally, as you edit, remember that all the power of emacs is at
+;;    your disposal.  It really is a fantastic tool.  You may even want to
+;;    take some time and read the emacs tutorial; perhaps not to learn the
+;;    native emacs key bindings, but to get a feel for all the things
+;;    emacs can do for you.  The emacs tutorial is available from the
+;;    emacs help function: "Gold-PF2 t"
+
+
+;; %% Starting TPU-edt
+
+;;    All you have to do to start TPU-edt, is turn it on.  This can be
+;;    done from the command line when running emacs.
+
+;;        prompt> emacs -f tpu-edt
+
+;;    If you've already started emacs, turn on TPU-edt using the tpu-edt
+;;    command.  First press `M-x' (that's usually `ESC' followed by `x')
+;;    and type `tpu-edt' followed by a carriage return.
+
+;;    If you like TPU-edt and want to use it all the time, you can start
+;;    TPU-edt using the emacs initialization file, .emacs.  Simply create
+;;    a .emacs file in your home directory containing the line:
+
+;;        (tpu-edt)
+
+;;    That's all you need to do to start TPU-edt.
+
+
+;; %% Customizing TPU-edt using the Emacs Initialization File
+
+;;    The following is a sample emacs initialization file.  It shows how to
+;;    invoke TPU-edt, and how to customize it.
+
+;;    ; .emacs - a sample emacs initialization file
+
+;;    ; Turn on TPU-edt
+;;    (tpu-edt)
+
+;;    ; Set scroll margins 10% (top) and 15% (bottom).
+;;    (tpu-set-scroll-margins "10%" "15%")       
+
+;;    ; Load the vtxxx terminal control functions.
+;;    (load "vt-control" t)
+
+;;    ; TPU-edt treats words like EDT; here's how to add word separators.
+;;    ; Note that backslash (\) and double quote (") are quoted with '\'.
+;;    (tpu-add-word-separators "]\\[-_,.\"=+()'/*#:!&;$")
+
+;;    ; Emacs is happy to save files without a final newline; other Unix
+;;    ; programs hate that!  Here we make sure that files end with newlines.
+;;    (setq require-final-newline t)
+
+;;    ; Emacs uses Control-s and Control-q.  Problems can occur when using
+;;    ; emacs on terminals that use these codes for flow control (Xon/Xoff
+;;    ; flow control).  These lines disable emacs' use of these characters.
+;;    (global-unset-key "\C-s")
+;;    (global-unset-key "\C-q")
+
+;;    ; The emacs universal-argument function is very useful.
+;;    ; This line maps universal-argument to Gold-PF1.
+;;    (define-key GOLD-SS3-map "P" 'universal-argument)          ; Gold-PF1
+
+;;    ; Make KP7 move by paragraphs, instead of pages.
+;;    (define-key SS3-map "w" 'tpu-paragraph)                    ; KP7
+
+;;    ; Repeat the preceding mappings for X-windows.
+;;    (cond
+;;     (window-system
+;;      (global-set-key [kp_7] 'tpu-paragraph)                   ; KP7
+;;      (define-key GOLD-map [kp_f1] 'universal-argument)))      ; GOLD-PF1
+
+;;    ; Display the TPU-edt version.
+;;    (tpu-version)
+
+
+;; %% Regular Expressions in TPU-edt
+
+;;    Gold-* toggles TPU-edt regular expression mode.  In regular expression
+;;    mode, find, find next, replace, and substitute accept emacs regular
+;;    expressions.  A complete list of emacs regular expressions can be found
+;;    using the emacs "info" command (it's somewhat like the VMS help
+;;    command).  Try the following sequence of commands:
+
+;;        DO info             <enter info mode>
+;;        m emacs             <select the "emacs" topic>
+;;        m regexs            <select the "regular expression" topic>
+
+;;    Type "q" to quit out of info mode.
+
+;;    There is a problem in regular expression mode when searching for empty
+;;    strings, like beginning-of-line (^) and end-of-line ($).  When searching
+;;    for these strings, find-next may find the current string, instead of the
+;;    next one.  This can cause global replace and substitute commands to loop
+;;    forever in the same location.  For this reason, commands like
+
+;;        replace "^" "> "       <add "> " to beginning of line>
+;;        replace "$" "00711"    <add "00711" to end of line>
+
+;;    may not work properly.
+
+;;    Commands like those above are very useful for adding text to the
+;;    beginning or end of lines.  They might work on a line-by-line basis, but
+;;    go into an infinite loop if the "all" response is specified.  If the
+;;    goal is to add a string to the beginning or end of a particular set of
+;;    lines TPU-edt provides functions to do this.
+
+;;        Gold-^  Add a string at BOL in region or buffer
+;;        Gold-$  Add a string at EOL in region or buffer
+
+;;    There is also a TPU-edt interface to the native emacs string replacement
+;;    commands.  Gold-/ invokes this command.  It accepts regular expressions
+;;    if TPU-edt is in regular expression mode.  Given a repeat count, it will
+;;    perform the replacement without prompting for confirmation.
+
+;;    This command replaces empty strings correctly, however, it has its
+;;    drawbacks.  As a native emacs command, it has a different interface
+;;    than the emulated TPU commands.  Also, it works only in the forward
+;;    direction, regardless of the current TPU-edt direction.
+
+;;; Code:
+
+
+;;;
+;;;  Version Information
+;;;
+(defconst tpu-version "4.2X" "TPU-edt version number.")
+
+
+;;;
+;;;  User Configurable Variables
+;;;
+(defconst tpu-have-ispell t
+  "*If non-nil (default), TPU-edt uses ispell for spell checking.")
+
+(defconst tpu-kill-buffers-silently nil
+  "*If non-nil, TPU-edt kills modified buffers without asking.")
+
+(defvar tpu-percent-scroll 75
+  "*Percentage of the screen to scroll for next/previous screen commands.")
+
+(defvar tpu-pan-columns 16
+  "*Number of columns the tpu-pan functions scroll left or right.")
+
+
+;;;
+;;;  Emacs version identifiers - currently referenced by
+;;;
+;;;     o tpu-mark              o tpu-set-mark
+;;;     o tpu-string-prompt     o tpu-regexp-prompt
+;;;     o tpu-edt-on            o tpu-load-xkeys
+;;;     o tpu-update-mode-line  o mode line section
+;;;
+(defconst tpu-emacs19-p (not (string-lessp emacs-version "19"))
+  "Non-nil if we are running Lucid Emacs or version 19.")
+
+(defconst tpu-lucid-emacs19-p
+  (and tpu-emacs19-p (string-match "Lucid" emacs-version))
+  "Non-nil if we are running Lucid Emacs version 19.")
+
+
+;;;
+;;;  Global Keymaps
+;;;
+(defvar CSI-map (make-sparse-keymap)
+  "Maps the CSI function keys on the VT100 keyboard.
+CSI is DEC's name for the sequence <ESC>[.")
+
+(defvar SS3-map (make-sparse-keymap)
+  "Maps the SS3 function keys on the VT100 keyboard.
+SS3 is DEC's name for the sequence <ESC>O.")
+
+(defvar GOLD-map (make-keymap)
+  "Maps the function keys on the VT100 keyboard preceded by PF1.
+GOLD is the ASCII 7-bit escape sequence <ESC>OP.")
+
+(defvar GOLD-CSI-map (make-sparse-keymap)
+  "Maps the function keys on the VT100 keyboard preceded by GOLD-CSI.")
+
+(defvar GOLD-SS3-map (make-sparse-keymap)
+  "Maps the function keys on the VT100 keyboard preceded by GOLD-SS3.")
+
+(defvar tpu-global-map nil "TPU-edt global keymap.")
+(defvar tpu-original-global-map (copy-keymap global-map)
+  "Original global keymap.")
+
+(and tpu-lucid-emacs19-p
+     (defvar minibuffer-local-ns-map (make-sparse-keymap)
+       "Hack to give Lucid Emacs the same maps as ordinary Emacs."))
+
+
+;;;
+;;;  Global Variables
+;;;
+(defvar tpu-edt-mode nil
+  "If non-nil, TPU-edt mode is active.")
+
+(defvar tpu-last-replaced-text ""
+  "Last text deleted by a TPU-edt replace command.")
+(defvar tpu-last-deleted-region ""
+  "Last text deleted by a TPU-edt remove command.")
+(defvar tpu-last-deleted-lines ""
+  "Last text deleted by a TPU-edt line-delete command.")
+(defvar tpu-last-deleted-words ""
+  "Last text deleted by a TPU-edt word-delete command.")
+(defvar tpu-last-deleted-char ""
+  "Last character deleted by a TPU-edt character-delete command.")
+
+(defvar tpu-searching-forward t
+  "If non-nil, TPU-edt is searching in the forward direction.")
+(defvar tpu-search-last-string ""
+  "Last text searched for by the TPU-edt search commands.")
+
+(defvar tpu-regexp-p nil
+  "If non-nil, TPU-edt uses regexp search and replace routines.")
+(defvar tpu-rectangular-p nil
+  "If non-nil, TPU-edt removes and inserts rectangles.")
+(defvar tpu-advance t
+  "True when TPU-edt is operating in the forward direction.")
+(defvar tpu-reverse nil
+  "True when TPU-edt is operating in the backward direction.")
+(defvar tpu-control-keys nil
+  "If non-nil, control keys are set to perform TPU functions.")
+(defvar tpu-xkeys-file nil
+  "File containing TPU-edt X key map.")
+
+(defvar tpu-rectangle-string nil
+  "Mode line string to identify rectangular mode.")
+(defvar tpu-direction-string nil
+  "Mode line string to identify current direction.")
+
+(defvar tpu-add-at-bol-hist nil
+  "History variable for tpu-edt-add-at-bol function.")
+(defvar tpu-add-at-eol-hist nil
+  "History variable for tpu-edt-add-at-eol function.")
+(defvar tpu-regexp-prompt-hist  nil
+  "History variable for search and replace functions.")
+
+
+;;;
+;;;  Buffer Local Variables
+;;;
+(defvar tpu-newline-and-indent-p nil
+  "If non-nil, Return produces a newline and indents.")
+(make-variable-buffer-local 'tpu-newline-and-indent-p)
+
+(defvar tpu-newline-and-indent-string nil
+  "Mode line string to identify AutoIndent mode.")
+(make-variable-buffer-local 'tpu-newline-and-indent-string)
+
+(defvar tpu-saved-delete-func nil
+  "Saved value of the delete key.")
+(make-variable-buffer-local 'tpu-saved-delete-func)
+
+(defvar tpu-buffer-local-map nil
+  "TPU-edt buffer local key map.")
+(make-variable-buffer-local 'tpu-buffer-local-map)
+
+
+;;;
+;;;  Mode Line - Modify the mode line to show the following
+;;;
+;;;     o  If the mark is set.
+;;;     o  Direction of motion.
+;;;     o  Active rectangle mode.
+;;;
+(defvar tpu-original-mode-line mode-line-format)
+(defvar tpu-original-mm-alist minor-mode-alist)
+
+(defvar tpu-mark-flag " ")
+(make-variable-buffer-local 'tpu-mark-flag)
+
+(defun tpu-set-mode-line (for-tpu)
+  "Set the mode for TPU-edt, or reset it to default Emacs."
+  (cond ((not for-tpu)
+	 (setq mode-line-format tpu-original-mode-line)
+	 (setq minor-mode-alist tpu-original-mm-alist))
+	(t
+	 (setq-default mode-line-format
+		       (list (purecopy "-")
+			     'mode-line-modified
+			     'mode-line-frame-identification
+			     'mode-line-buffer-identification
+			     (purecopy "  ")
+			     'global-mode-string
+			     (purecopy "  ")
+			     'tpu-mark-flag
+			     (purecopy " %[(")
+			     'mode-name 'mode-line-process 'minor-mode-alist
+			     (purecopy "%n")
+			     (purecopy ")%]--")
+			     (purecopy '(line-number-mode "L%l--"))
+			     (purecopy '(column-number-mode "C%c--"))
+			     (purecopy '(-3 . "%p"))
+			     (purecopy "-%-")))
+	 (or (assq 'tpu-newline-and-indent-p minor-mode-alist)
+	     (setq minor-mode-alist
+		   (cons '(tpu-newline-and-indent-p
+			   tpu-newline-and-indent-string)
+			 minor-mode-alist)))
+	 (or (assq 'tpu-rectangular-p minor-mode-alist)
+	     (setq minor-mode-alist
+		   (cons '(tpu-rectangular-p tpu-rectangle-string)
+			 minor-mode-alist)))
+	 (or (assq 'tpu-direction-string minor-mode-alist)
+	     (setq minor-mode-alist
+		   (cons '(tpu-direction-string tpu-direction-string)
+			 minor-mode-alist))))))
+
+(defun tpu-update-mode-line nil
+  "Make sure mode-line in the current buffer reflects all changes."
+  (setq tpu-mark-flag (if (tpu-mark) "M" " "))
+  (cond (tpu-emacs19-p (force-mode-line-update))
+	(t (set-buffer-modified-p (buffer-modified-p)) (sit-for 0))))
+
+(cond (tpu-lucid-emacs19-p
+       (add-hook 'zmacs-deactivate-region-hook 'tpu-update-mode-line)
+       (add-hook 'zmacs-activate-region-hook 'tpu-update-mode-line))
+      (tpu-emacs19-p
+       (add-hook 'activate-mark-hook 'tpu-update-mode-line)
+       (add-hook 'deactivate-mark-hook 'tpu-update-mode-line)))
+
+
+;;;
+;;;  Match Markers -
+;;;
+;;;     Set in:  Search
+;;;
+;;;     Used in: Replace, Substitute, Store-Text, Cut/Remove,
+;;;              Append, and Change-Case
+;;;
+(defvar tpu-match-beginning-mark (make-marker))
+(defvar tpu-match-end-mark (make-marker))
+
+(defun tpu-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 tpu-match-beginning-mark (copy-marker (1+ (match-beginning 0))))
+  (setq tpu-match-end-mark (copy-marker (match-end 0))))
+
+(defun tpu-unset-match nil
+  "Unset match beginning and end markers."
+  (set-marker tpu-match-beginning-mark nil)
+  (set-marker tpu-match-end-mark nil))
+
+(defun tpu-match-beginning nil
+  "Returns the location of the last match beginning."
+  (1- (marker-position tpu-match-beginning-mark)))
+
+(defun tpu-match-end nil
+  "Returns the location of the last match end."
+  (marker-position tpu-match-end-mark))
+
+(defun tpu-check-match nil
+  "Returns t if point is between tpu-match markers.
+Otherwise sets the tpu-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 tpu-match-beginning-mark) (current-buffer))
+	  (>= (point) (1- (marker-position tpu-match-beginning-mark)))
+	  (or
+	   (< (point) (marker-position tpu-match-end-mark))
+	   (and (= (1- (marker-position tpu-match-beginning-mark))
+		   (marker-position tpu-match-end-mark))
+		(= (marker-position tpu-match-end-mark) (point))))) t)
+	(t
+	 (tpu-unset-match) nil)))
+
+(defun tpu-show-match-markers nil
+  "Show the values of the match markers."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (if (markerp tpu-match-beginning-mark)
+      (let ((beg (marker-position tpu-match-beginning-mark)))
+	(message "(%s, %s) in %s -- current %s in %s"
+		 (if beg (1- beg) nil)
+		 (marker-position tpu-match-end-mark)
+		 (marker-buffer tpu-match-end-mark)
+		 (point) (current-buffer)))))
+
+
+;;;
+;;;  Utilities
+;;;
+(defun tpu-caar (thingy) (car (car thingy)))
+(defun tpu-cadr (thingy) (car (cdr thingy)))
+
+(defun tpu-mark nil
+  "TPU-edt version of the mark function.
+Return the appropriate value of the mark for the current
+version of Emacs."
+  (cond (tpu-lucid-emacs19-p (mark (not zmacs-regions)))
+	(tpu-emacs19-p (and mark-active (mark (not transient-mark-mode))))
+	(t (mark))))
+
+(defun tpu-set-mark (pos)
+  "TPU-edt verion of the `set-mark' function.
+Sets the mark at POS and activates the region according to the
+current version of Emacs."
+  (set-mark pos)
+  (and tpu-lucid-emacs19-p pos (zmacs-activate-region)))
+
+(defun tpu-string-prompt (prompt history-symbol)
+  "Read a string with PROMPT."
+  (if tpu-emacs19-p
+      (read-from-minibuffer prompt nil nil nil history-symbol)
+    (read-string prompt)))
+
+(defvar tpu-last-answer nil "Most recent response to tpu-y-or-n-p.")
+
+(defun tpu-y-or-n-p (prompt &optional not-yes)
+  "Prompt for a y or n answer with positive default.
+Optional second argument NOT-YES changes default to negative.
+Like Emacs `y-or-n-p', but also accepts space as y and DEL as n."
+  (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 tpu-last-answer t))
+	      ((or (= ans ?n) (= ans ?N) (= ans ?\C-?))
+	       (setq tpu-last-answer nil))
+	      ((= ans ?\r) (setq tpu-last-answer (not not-yes)))
+	      (t
+	       (setq doit t) (beep)
+	       (message "Please answer y or n.  %s[%s]"
+			prompt (if not-yes "n" "y")))))))
+  tpu-last-answer)
+
+(defun tpu-local-set-key (key func)
+  "Replace a key in the TPU-edt local key map.
+Create the key map if necessary."
+  (cond ((not (keymapp tpu-buffer-local-map))
+	 (setq tpu-buffer-local-map (if (current-local-map)
+					(copy-keymap (current-local-map))
+				      (make-sparse-keymap)))
+	 (use-local-map tpu-buffer-local-map)))
+  (local-set-key key func))
+
+(defun tpu-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))
+
+
+;;;
+;;;  Breadcrumbs
+;;;
+(defvar tpu-breadcrumb-plist nil
+  "The set of user-defined markers (breadcrumbs), as a plist.")
+
+(defun tpu-drop-breadcrumb (num)
+  "Drops a breadcrumb that can be returned to later with goto-breadcrumb."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (put tpu-breadcrumb-plist num (list (current-buffer) (point)))
+  (message "Mark %d set." num))
+
+(defun tpu-goto-breadcrumb (num)
+  "Returns to a breadcrumb set with drop-breadcrumb."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (cond ((get tpu-breadcrumb-plist num)
+	 (switch-to-buffer (car (get tpu-breadcrumb-plist num)))
+	 (goto-char (tpu-cadr (get tpu-breadcrumb-plist num)))
+	 (message "mark %d found." num))
+	(t
+	 (message "mark %d not found." num))))
+
+
+;;;
+;;;  Miscellaneous
+;;;
+(defun tpu-change-case (num)
+  "Change the case of the character under the cursor or region.
+Accepts a prefix argument of the number of characters to invert."
+  (interactive "p")
+  (cond ((tpu-mark)
+	 (let ((beg (region-beginning)) (end (region-end)))
+	   (while (> end beg)
+	     (funcall (if (= (downcase (char-after beg)) (char-after beg))
+			  'upcase-region 'downcase-region)
+		      beg (1+ beg))
+	     (setq beg (1+ beg)))
+	   (tpu-unselect t)))
+	((tpu-check-match)
+	 (let ((beg (tpu-match-beginning)) (end (tpu-match-end)))
+	   (while (> end beg)
+	     (funcall (if (= (downcase (char-after beg)) (char-after beg))
+			  'upcase-region 'downcase-region)
+		      beg (1+ beg))
+	     (setq beg (1+ beg)))
+	   (tpu-unset-match)))
+	(t
+	 (while (> num 0)
+	   (funcall (if (= (downcase (following-char)) (following-char))
+			'upcase-region 'downcase-region)
+		    (point) (1+ (point)))
+	   (forward-char (if tpu-reverse -1 1))
+	   (setq num (1- num))))))
+
+(defun tpu-fill (num)
+  "Fill paragraph or marked region.
+With argument, fill and justify."
+  (interactive "P")
+  (cond ((tpu-mark)
+	 (fill-region (point) (tpu-mark) num)
+	 (tpu-unselect t))
+	(t
+	 (fill-paragraph num))))
+
+(defun tpu-version nil
+  "Print the TPU-edt version number."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (message
+   "TPU-edt version %s by Rob Riepel (riepel@networking.stanford.edu)"
+   tpu-version))
+
+(defun tpu-reset-screen-size (height width)
+  "Sets the screen size."
+  (interactive "nnew screen height: \nnnew screen width: ")
+  (setq zmacs-region-stays t)
+  (set-frame-height height)
+  (set-frame-width width))
+
+(defun tpu-toggle-newline-and-indent nil
+  "Toggle between 'newline and indent' and 'simple newline'."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (cond (tpu-newline-and-indent-p
+         (setq tpu-newline-and-indent-string "")
+         (setq tpu-newline-and-indent-p nil)
+         (tpu-local-set-key "\C-m" 'newline))
+        (t
+         (setq tpu-newline-and-indent-string " AutoIndent")
+         (setq tpu-newline-and-indent-p t)
+         (tpu-local-set-key "\C-m" 'newline-and-indent)))
+  (tpu-update-mode-line)
+  (and (interactive-p)
+       (message "Carriage return inserts a newline%s"
+		(if tpu-newline-and-indent-p " and indents." "."))))
+
+(defun tpu-spell-check nil
+  "Checks the spelling of the region, or of the entire buffer if no
+ region is selected."
+  (interactive)
+  (cond (tpu-have-ispell
+	 (if (tpu-mark) (ispell-region (tpu-mark) (point)) (ispell-buffer)))
+	(t
+	 (if (tpu-mark) (spell-region (tpu-mark) (point)) (spell-buffer))))
+  (if (tpu-mark) (tpu-unselect t)))
+
+(defun tpu-toggle-overwrite-mode nil
+  "Switches in and out of overwrite mode"
+  (interactive)
+  (setq zmacs-region-stays t)
+  (cond (overwrite-mode
+	 (tpu-local-set-key "\177" tpu-saved-delete-func)
+	 (overwrite-mode 0))
+	(t
+	 (setq tpu-saved-delete-func (local-key-binding "\177"))
+	 (tpu-local-set-key "\177" 'picture-backward-clear-column)
+	 (overwrite-mode 1))))
+
+(defun tpu-special-insert (num)
+  "Insert a character or control code according to
+its ASCII decimal value."
+  (interactive "P")
+  (setq zmacs-region-stays t)
+  (if overwrite-mode (delete-char 1))
+  (insert (if num num 0)))
+
+(defun tpu-quoted-insert (num)
+  "Read next input character and insert it.
+This is useful for inserting control characters."
+  (interactive "*p")
+  (setq zmacs-region-stays t)
+  (let ((char (read-char)) )
+    (if overwrite-mode (delete-char num))
+    (insert-char char num)))
+
+
+;;;
+;;;  TPU line-mode commands
+;;;
+(defun tpu-include (file)
+  "TPU-like include file"
+  (interactive "fInclude file: ")
+  (setq zmacs-region-stays t)
+  (save-excursion
+    (insert-file file)
+    (message "")))
+
+(defun tpu-get (file)
+  "TPU-like get file"
+  (interactive "FFile to get: ")
+  (setq zmacs-region-stays t)
+  (find-file file))
+
+(defun tpu-what-line nil
+  "Tells what line the point is on,
+ and the total number of lines in the buffer."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (if (eobp)
+      (message "You are at the End of Buffer.  The last line is %d."
+	       (count-lines 1 (point-max)))
+    (message "Line %d of %d"
+	     (count-lines 1 (1+ (point)))
+	     (count-lines 1 (point-max)))))
+
+(defun tpu-exit nil
+  "Exit the way TPU does, save current buffer and ask about others."
+  (interactive)
+  (if (not (eq (recursion-depth) 0))
+      (exit-recursive-edit)
+    (progn (save-buffer) (save-buffers-kill-emacs))))
+
+(defun tpu-quit nil
+  "Quit the way TPU does, ask to make sure changes should be abandoned."
+  (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 (tpu-y-or-n-p
+		 "Modifications will not be saved, continue quitting? ")
+		(kill-emacs t) (setq working nil)))
+	(setq list (cdr list))))
+    (if working (kill-emacs t))))
+
+
+;;;
+;;;  Command and Function Aliases
+;;;
+;;;###autoload
+(fset 'tpu-edt-mode 'tpu-edt-on)
+(fset 'TPU-EDT-MODE 'tpu-edt-on)
+
+;;;###autoload
+(fset 'tpu-edt 'tpu-edt-on)
+(fset 'TPU-EDT 'tpu-edt-on)
+
+(fset 'exit 'tpu-exit)
+(fset 'EXIT 'tpu-exit)
+
+(fset 'Get 'tpu-get)
+(fset 'GET 'tpu-get)
+
+(fset 'include 'tpu-include)
+(fset 'INCLUDE 'tpu-include)
+
+(fset 'quit 'tpu-quit)
+(fset 'QUIT 'tpu-quit)
+
+(fset 'spell 'tpu-spell-check)
+(fset 'SPELL 'tpu-spell-check)
+
+(fset 'what\ line 'tpu-what-line)
+(fset 'WHAT\ LINE 'tpu-what-line)
+
+(fset 'replace 'tpu-lm-replace)
+(fset 'REPLACE 'tpu-lm-replace)
+
+;; Apparently TPU users really expect to do M-x help RET to get help.
+;; So it is really necessary to redefine this.
+(fset 'help 'tpu-help)
+(fset 'HELP 'tpu-help)
+
+(fset 'set\ cursor\ free 'tpu-set-cursor-free)
+(fset 'SET\ CURSOR\ FREE 'tpu-set-cursor-free)
+
+(fset 'set\ cursor\ bound 'tpu-set-cursor-bound)
+(fset 'SET\ CURSOR\ BOUND 'tpu-set-cursor-bound)
+
+(fset 'set\ scroll\ margins 'tpu-set-scroll-margins)
+(fset 'SET\ SCROLL\ MARGINS 'tpu-set-scroll-margins)
+
+
+;; Around emacs version 18.57, function line-move was renamed to
+;; next-line-internal.  If we're running under an older emacs,
+;; make next-line-internal equivalent to line-move.
+
+(if (not (fboundp 'next-line-internal)) (fset 'next-line-internal 'line-move))
+
+
+;;;
+;;;  Help
+;;;
+(defconst tpu-help-keypad-map "\f
+          _______________________    _______________________________
+         | HELP  |      Do       |  |       |       |       |       |
+         |KeyDefs|               |  |       |       |       |       |
+         |_______|_______________|  |_______|_______|_______|_______|
+          _______________________    _______________________________
+         | Find  |Insert |Remove |  | Gold  | HELP  |FndNxt | Del L |
+         |       |       |Sto Tex|  |  key  |E-Help | Find  |Undel L|
+         |_______|_______|_______|  |_______|_______|_______|_______|
+         |Select |Pre Scr|Nex Scr|  | Page  | Sect  |Append | Del W |
+         | Reset |Pre Win|Nex Win|  |  Do   | Fill  |Replace|Undel W|
+         |_______|_______|_______|  |_______|_______|_______|_______|
+                 |Move up|          |Forward|Reverse|Remove | Del C |
+                 |  Top  |          |Bottom |  Top  |Insert |Undel C|
+          _______|_______|_______   |_______|_______|_______|_______|
+         |Mov Lef|Mov Dow|Mov Rig|  | Word  |  EOL  | Char  |       |
+         |StaOfLi|Bottom |EndOfLi|  |ChngCas|Del EOL|SpecIns| Enter |
+         |_______|_______|_______|  |_______|_______|_______|       |
+                                    |     Line      |Select | Subs  |
+                                    |   Open Line   | Reset |       |
+                                    |_______________|_______|_______|
+")
+
+(defconst tpu-help-text "
+\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\f
+
+      Control Characters
+
+      ^A  toggle insert and overwrite
+      ^B  recall
+      ^E  end of line
+
+      ^G  Cancel current operation
+      ^H  beginning of line
+      ^J  delete previous word
+
+      ^K  learn
+      ^L  insert page break
+      ^R  remember (during learn), re-center
+
+      ^U  delete to beginning of line
+      ^V  quote
+      ^W  refresh
+
+      ^Z  exit
+    ^X^X  exchange point and mark - useful for checking region boundaries
+
+\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\f
+       Gold-<key> Functions
+
+       B     Next Buffer - display the next buffer (all buffers)
+       C     Recall - edit and possibly repeat previous commands
+       E     Exit - save current buffer and ask about others
+       G     Get - load a file into a new edit buffer
+
+       I     Include - include a file in this buffer
+       K     Kill Buffer - abandon edits and delete buffer
+       M     Buffer Menu - display a list of all buffers
+       N     Next File Buffer - display next buffer containing a file
+
+       O     Occur - show following lines containing REGEXP
+       Q     Quit - exit without saving anything
+       R     Toggle rectangular mode for remove and insert
+       S     Search and substitute - line mode REPLACE command
+
+      ^T     Toggle control key bindings between TPU and emacs
+       U     Undo - undo the last edit
+       W     Write - save current buffer
+       X     Exit - save all modified buffers and exit
+
+\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\f
+
+  More extensive documentation on TPU-edt can be found in the `Commentary'
+  section of tpu-edt.el.  This section can be accessed through the standard
+  Emacs help facility using the `p' option.  Once you exit TPU-edt Help, one
+  of the following key sequences is sure to get you there.
+
+    ^h p        if you're not yet using TPU-edt
+    Gold-PF2 p  if you're using TPU-edt
+
+  Alternatively, fire up Emacs help from the command prompt, with
+
+    M-x help-for-help <CR> p <CR>
+
+  Where `M-x' might be any of `Gold-KP7', 'Do', or 'ESC-x'.
+
+  When you successfully invoke this part of the Emacs help facility, you
+  will see a buffer named `*Finder*' listing a number of topics.  Look for
+  tpu-edt under `emulations'.
+
+\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\f
+
+   *** No more help, use P to view previous screen")
+
+(defvar tpu-help-enter (format "%s" "\eOM"))    ; tpu-help enter key symbol
+(defvar tpu-help-return (format "%s" "\r"))     ; tpu-help enter key symbol
+(defvar tpu-help-N "N")                         ; tpu-help "N" symbol
+(defvar tpu-help-n "n")                         ; tpu-help "n" symbol
+(defvar tpu-help-P "P")                         ; tpu-help "P" symbol
+(defvar tpu-help-p "p")                         ; tpu-help "p" symbol
+
+(defun tpu-help nil
+  "Display TPU-edt help."
+  (interactive)
+  (setq zmacs-region-stays t)
+  ;; Save current window configuration
+  (save-window-excursion
+    ;; Create and fill help buffer if necessary
+    (if (not (get-buffer "*TPU-edt Help*"))
+	(progn (generate-new-buffer "*TPU-edt Help*")
+	       (switch-to-buffer "*TPU-edt Help*")
+	       (insert tpu-help-keypad-map)
+	       (insert tpu-help-text)
+	       (setq buffer-read-only t)))
+
+    ;; Display the help buffer
+    (switch-to-buffer "*TPU-edt Help*")
+    (delete-other-windows)
+    (tpu-move-to-beginning)
+    (forward-line 1)
+    (tpu-line-to-top-of-window)
+
+    ;; Prompt for keys to describe, based on screen state (split/not split)
+    (let ((key nil) (fkey nil) (split nil))
+      (while (not (equal tpu-help-return fkey))
+	(if split
+	    (setq key
+		  (read-key-sequence
+		   "Press the key you want help on (RET=exit, ENTER=redisplay, N=next, 
+P=prev): "))
+	  (setq key
+		(read-key-sequence
+		 "Press the key you want help on (RET to exit, N next screen, P prev 
+screen): ")))
+
+	;; Process the read key
+	;;
+	;;    ENTER   -  Display just the help window
+	;;    N or n  -  Next help or describe-key screen
+	;;    P or p  -  Previous help or describe-key screen
+	;;    RETURN  -  Exit from TPU-help
+	;;    default -  describe the key
+	;;
+	(setq fkey (format "%s" key))
+	(cond ((equal tpu-help-enter fkey)
+	       (setq split nil)
+	       (delete-other-windows))
+	      ((or (equal tpu-help-N fkey) (equal tpu-help-n fkey))
+	       (cond (split
+	              (condition-case nil
+	        	  (scroll-other-window 8)
+	        	(error nil)))
+	             (t
+	              (forward-page)
+	              (forward-line 1)
+	              (tpu-line-to-top-of-window))))
+	      ((or (equal tpu-help-P fkey) (equal tpu-help-p fkey))
+	       (cond (split
+	              (condition-case nil
+	        	  (scroll-other-window -8)
+	        	(error nil)))
+	             (t
+	              (backward-page)
+	              (forward-line 1)
+	              (tpu-line-to-top-of-window))))
+	      ((not (equal tpu-help-return fkey))
+	       (setq split t)
+	       (describe-key key)
+	       ;; If the key is undefined, leave the
+	       ;;   message in the mini-buffer for 3 seconds
+	       (if (not (key-binding key)) (sit-for 3))))))))
+
+
+;;;
+;;;  Auto-insert
+;;;
+(defun tpu-insert-escape nil
+  "Inserts an escape character, and so becomes the escape-key alias."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (insert "\e"))
+
+(defun tpu-insert-formfeed nil
+  "Inserts a formfeed character."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (insert "\C-L"))
+
+
+;;;
+;;;  Define key
+;;;
+(defvar tpu-saved-control-r nil "Saved value of Control-r.")
+
+(defun tpu-end-define-macro-key (key)
+  "Ends the current macro definition"
+  (interactive "kPress the key you want to use to do what was just learned: ")
+  (setq zmacs-region-stays t)
+  (end-kbd-macro nil)
+  (global-set-key key last-kbd-macro)
+  (global-set-key "\C-r" tpu-saved-control-r))
+
+(defun tpu-define-macro-key nil
+  "Bind a set of keystrokes to a single key, or key combination."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (setq tpu-saved-control-r (global-key-binding "\C-r"))
+  (global-set-key "\C-r" 'tpu-end-define-macro-key)
+  (start-kbd-macro nil))
+
+
+;;;
+;;;  Buffers and Windows
+;;;
+(defun tpu-kill-buffer nil
+  "Kills the current buffer.  If tpu-kill-buffers-silently is non-nil,
+kills modified buffers without asking."
+  (interactive)
+  (if tpu-kill-buffers-silently (set-buffer-modified-p nil))
+  (kill-buffer (current-buffer)))
+
+(defun tpu-save-all-buffers-kill-emacs nil
+  "Save all buffers and exit emacs."
+  (interactive)
+  (let ((delete-old-versions t))
+    (save-buffers-kill-emacs t)))
+
+(defun tpu-write-current-buffers nil
+  "Save all modified buffers without exiting."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (save-some-buffers t))
+
+(defun tpu-next-buffer nil
+  "Go to next buffer in ring."
+  (interactive)
+  (switch-to-buffer (car (reverse (buffer-list)))))
+
+(defun tpu-next-file-buffer nil
+  "Go to next buffer in ring that is visiting a file or directory."
+  (interactive)
+  (let ((list (tpu-make-file-buffer-list (buffer-list))))
+    (setq list (delq (current-buffer) list))
+    (if (not list) (error "No other buffers."))
+    (switch-to-buffer (car (reverse list)))))
+
+(defun tpu-make-file-buffer-list (buffer-list)
+  "Returns names from BUFFER-LIST excluding those beginning with a space or 
+star."
+  (delq nil (mapcar '(lambda (b)
+                       (if (or (= (aref (buffer-name b) 0) ? )
+                               (= (aref (buffer-name b) 0) ?*)) nil b))
+                    buffer-list)))
+
+(defun tpu-next-window nil
+  "Move to the next window."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (if (one-window-p) (message "There is only one window on screen.")
+    (other-window 1)))
+
+(defun tpu-previous-window nil
+  "Move to the previous window."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (if (one-window-p) (message "There is only one window on screen.")
+    (select-window (previous-window))))
+
+
+;;;
+;;;  Search
+;;;
+(defun tpu-toggle-regexp nil
+  "Switches in and out of regular expression search and replace mode."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (setq tpu-regexp-p (not tpu-regexp-p))
+  (tpu-set-search)
+  (and (interactive-p)
+       (message "Regular expression search and substitute %sabled."
+		(if tpu-regexp-p "en" "dis"))))
+
+(defun tpu-regexp-prompt (prompt)
+  "Read a string, adding 'RE' to the prompt if tpu-regexp-p is set."
+  (let ((re-prompt (concat (if tpu-regexp-p "RE ") prompt)))
+    (if tpu-emacs19-p
+	(read-from-minibuffer re-prompt nil nil nil 'tpu-regexp-prompt-hist)
+      (read-string re-prompt))))
+
+(defun tpu-search nil
+  "Search for a string or regular expression.
+The search is performed in the current direction."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (tpu-set-search)
+  (tpu-search-internal ""))
+
+(defun tpu-search-forward nil
+  "Search for a string or regular expression.
+The search is begins in the forward direction."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (setq tpu-searching-forward t)
+  (tpu-set-search t)
+  (tpu-search-internal ""))
+
+(defun tpu-search-reverse nil
+  "Search for a string or regular expression.
+The search is begins in the reverse direction."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (setq tpu-searching-forward nil)
+  (tpu-set-search t)
+  (tpu-search-internal ""))
+
+(defun tpu-search-again nil
+  "Search for the same string or regular expression as last time.
+The search is performed in the current direction."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (tpu-search-internal tpu-search-last-string))
+
+;;  tpu-set-search defines the search functions used by the TPU-edt internal
+;;  search function.  It should be called whenever the direction changes, or
+;;  the regular expression mode is turned on or off.  It can also be called
+;;  to ensure that the next search will be in the current direction.  It is
+;;  called from:
+
+;;       tpu-advance                   tpu-backup
+;;       tpu-toggle-regexp             tpu-toggle-search-direction (t)
+;;       tpu-search                    tpu-lm-replace
+;;       tpu-search-forward (t)        tpu-search-reverse (t)
+;;       tpu-search-forward-exit (t)   tpu-search-backward-exit (t)
+
+(defun tpu-set-search (&optional arg)
+  "Set the search functions and set the search direction to the current
+direction.  If an argument is specified, don't set the search direction."
+  (if (not arg) (setq tpu-searching-forward (if tpu-advance t nil)))
+  (cond (tpu-searching-forward
+	 (cond (tpu-regexp-p
+		(fset 'tpu-emacs-search 're-search-forward)
+		(fset 'tpu-emacs-rev-search 're-search-backward))
+	       (t
+		(fset 'tpu-emacs-search 'search-forward)
+		(fset 'tpu-emacs-rev-search 'search-backward))))
+	(t
+	 (cond (tpu-regexp-p
+		(fset 'tpu-emacs-search 're-search-backward)
+		(fset 'tpu-emacs-rev-search 're-search-forward))
+	       (t
+		(fset 'tpu-emacs-search 'search-backward)
+		(fset 'tpu-emacs-rev-search 'search-forward))))))
+
+(defun tpu-search-internal (pat &optional quiet)
+  "Search for a string or regular expression."
+  (setq tpu-search-last-string
+	(if (not (string= "" pat)) pat (tpu-regexp-prompt "Search: ")))
+
+  (tpu-unset-match)
+  (tpu-adjust-search)
+
+  (let ((case-fold-search
+	 (and case-fold-search (tpu-check-search-case tpu-search-last-string))))
+
+    (cond ((tpu-emacs-search tpu-search-last-string nil t)
+	   (tpu-set-match) (goto-char (tpu-match-beginning)))
+
+	  (t
+	   (tpu-adjust-search t)
+	   (let ((found nil) (pos nil))
+	     (save-excursion
+	       (let ((tpu-searching-forward (not tpu-searching-forward)))
+		 (tpu-adjust-search)
+		 (setq found (tpu-emacs-rev-search tpu-search-last-string nil t))
+		 (setq pos (match-beginning 0))))
+
+	     (cond
+	      (found
+	       (cond ((tpu-y-or-n-p
+		       (format "Found in %s direction.  Go there? "
+			       (if tpu-searching-forward "reverse" "forward")))
+		      (goto-char pos) (tpu-set-match)
+		      (tpu-toggle-search-direction))))
+
+	      (t
+	       (if (not quiet)
+		   (message
+		    "%sSearch failed: \"%s\""
+		    (if tpu-regexp-p "RE " "") tpu-search-last-string)))))))))
+
+(fset 'tpu-search-internal-core (symbol-function 'tpu-search-internal))
+
+(defun tpu-check-search-case (string)
+  "Returns t if string contains upper case."
+  ;; if using regexp, eliminate upper case forms (\B \W \S.)
+  (if tpu-regexp-p
+      (let ((pat (copy-sequence string)) (case-fold-search nil) (pos 0))
+	(while (setq pos (string-match "\\\\\\\\" pat)) (aset pat (+ 1 pos) ?.))
+	(while (setq pos (string-match "\\\\B" pat)) (aset pat (+ 1 pos) ?.))
+	(while (setq pos (string-match "\\\\W" pat)) (aset pat (+ 1 pos) ?.))
+	(while (setq pos (string-match "\\\\S." pat))
+	  (aset pat (+ 1 pos) ?.) (aset pat (+ 2 pos) ?.))
+	(string-equal pat (downcase pat)))
+    (string-equal string (downcase string))))
+
+(defun tpu-adjust-search (&optional arg)
+  "For forward searches, move forward a character before searching,
+and backward a character after a failed search.  Arg means end of search."
+  (if tpu-searching-forward
+      (cond (arg (if (not (bobp)) (forward-char -1)))
+	    (t (if (not (eobp)) (forward-char 1))))))
+
+(defun tpu-toggle-search-direction nil
+  "Toggle the TPU-edt search direction.
+Used for reversing a search in progress."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (setq tpu-searching-forward (not tpu-searching-forward))
+  (tpu-set-search t)
+  (and (interactive-p)
+       (message "Searching %sward."
+		(if tpu-searching-forward "for" "back"))))
+
+(defun tpu-search-forward-exit nil
+  "Set search direction forward and exit minibuffer."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (setq tpu-searching-forward t)
+  (tpu-set-search t)
+  (exit-minibuffer))
+
+(defun tpu-search-backward-exit nil
+  "Set search direction backward and exit minibuffer."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (setq tpu-searching-forward nil)
+  (tpu-set-search t)
+  (exit-minibuffer))
+
+
+;;;
+;;;  Select / Unselect
+;;;
+(defun tpu-select (&optional quiet)
+  "Sets the mark to define one end of a region."
+  (interactive "P")
+  (cond ((tpu-mark)
+	 (tpu-unselect quiet))
+	(t
+	 (tpu-set-mark (point))
+	 (tpu-update-mode-line)
+	 (if (not quiet) (message "Move the text cursor to select text.")))))
+
+(defun tpu-unselect (&optional quiet)
+  "Removes the mark to unselect the current region."
+  (interactive "P")
+  (setq mark-ring nil)
+  (tpu-set-mark nil)
+  (tpu-update-mode-line)
+  (if (not quiet) (message "Selection canceled.")))
+
+
+;;;
+;;;  Delete / Cut
+;;;
+(defun tpu-toggle-rectangle nil
+  "Toggle rectangular mode for remove and insert."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (setq tpu-rectangular-p (not tpu-rectangular-p))
+  (setq tpu-rectangle-string (if tpu-rectangular-p " Rect" ""))
+  (tpu-update-mode-line)
+  (and (interactive-p)
+       (message "Rectangular cut and paste %sabled."
+		(if tpu-rectangular-p "en" "dis"))))
+
+(defun tpu-arrange-rectangle nil
+  "Adjust point and mark to mark upper left and lower right
+corners of a rectangle."
+  (let ((mc (current-column))
+	(pc (progn (exchange-point-and-mark) (current-column))))
+
+    (cond ((> (point) (tpu-mark))                  ; point on lower line
+	   (cond ((> pc mc)                        ; point @  lower-right
+		  (exchange-point-and-mark))       ; point -> upper-left
+
+		 (t	                           ; point @  lower-left
+		  (move-to-column-force mc)        ; point -> lower-right
+		  (exchange-point-and-mark)        ; point -> upper-right
+		  (move-to-column-force pc))))     ; point -> upper-left
+
+	  (t                                       ; point on upper line
+	   (cond ((> pc mc)                        ; point @  upper-right
+		  (move-to-column-force mc)        ; point -> upper-left
+		  (exchange-point-and-mark)        ; point -> lower-left
+		  (move-to-column-force pc)        ; point -> lower-right
+		  (exchange-point-and-mark)))))))  ; point -> upper-left
+
+(defun tpu-cut-text nil
+  "Delete the selected region.
+The text is saved for the tpu-paste command."
+  (interactive)
+  (cond ((tpu-mark)
+	 (cond (tpu-rectangular-p
+		(tpu-arrange-rectangle)
+		(picture-clear-rectangle (point) (tpu-mark) (not overwrite-mode))
+		(tpu-unselect t))
+	       (t
+		(setq tpu-last-deleted-region
+		      (buffer-substring (tpu-mark) (point)))
+		(delete-region (tpu-mark) (point))
+		(tpu-unselect t))))
+	((tpu-check-match)
+	 (let ((beg (tpu-match-beginning)) (end (tpu-match-end)))
+	   (setq tpu-last-deleted-region (buffer-substring beg end))
+	   (delete-region beg end)
+	   (tpu-unset-match)))
+	(t
+	 (error "No selection active."))))
+
+(defun tpu-store-text nil
+  "Copy the selected region to the cut buffer without deleting it.
+The text is saved for the tpu-paste command."
+  (interactive)
+  (setq zmacs-region-stays t)
+  (cond ((tpu-mark)
+	 (cond (tpu-rectangular-p
+		(save-excursion
+		  (tpu-arrange-rectangle)
+		  (setq picture-killed-rectangle
+			(extract-rectangle (point) (tpu-mark))))
+		(tpu-unselect t))
+	       (t
+		(setq tpu-last-deleted-region
+		      (buffer-substring (tpu-mark) (point)))
+		(tpu-unselect t))))
+	((tpu-check-match)
+	 (setq tpu-last-deleted-region
+	       (buffer-substring (tpu-match-beginning) (tpu-match-end)))
+	 (tpu-unset-match))
+	(t
+	 (error "No selection active."))))
+
+(defun tpu-cut (arg)
+  "Copy selected region to the cut buffer.  In the absence of an
+argument, delete the selected region too."
+  (interactive "P")
+  (if arg (tpu-store-text) (tpu-cut-text)))
+
+(defun tpu-append-region (arg)
+  "Append selected region to the tpu-cut buffer.  In the absence of an
+argument, delete the selected region too."
+  (interactive "P")
+  (cond ((tpu-mark)
+	 (let ((beg (region-beginning)) (end (region-end)))
+	   (setq tpu-last-deleted-region
+		 (concat tpu-last-deleted-region
+			 (buffer-substring beg end)))
+	   (if (not arg) (delete-region beg end))
+	   (tpu-unselect t)))
+	((tpu-check-match)
+	 (let ((beg (tpu-match-beginning)) (end (tpu-match-end)))
+	   (setq tpu-last-deleted-region
+		 (concat tpu-last-deleted-region
+			 (buffer-substring beg end)))
+	   (if (not arg) (delete-region beg end))
+	   (tpu-unset-match)))
+	(t
+	 (error "No selection active."))))
+
+(defun tpu-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 TPU-edt undelete-lines command."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (let ((beg (point)))
+    (forward-line num)
+    (if (not (eq (preceding-char) ?\n))
+        (insert "\n"))
+    (setq tpu-last-deleted-lines
+          (buffer-substring beg (point)))
+    (delete-region beg (point))))
+
+(defun tpu-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 TPU-edt undelete-lines command."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (let ((beg (point)))
+    (forward-char 1)
+    (end-of-line num)
+    (setq tpu-last-deleted-lines
+          (buffer-substring beg (point)))
+    (delete-region beg (point))))
+
+(defun tpu-delete-to-bol (num)
+  "Delete text back to beginning of line.
+With argument, delete up to to Nth line-end past point.
+They are saved for the TPU-edt undelete-lines command."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (let ((beg (point)))
+    (tpu-next-beginning-of-line num)
+    (setq tpu-last-deleted-lines
+          (buffer-substring (point) beg))
+    (delete-region (point) beg)))
+
+(defun tpu-delete-current-word (num)
+  "Delete one or specified number of words after point.
+They are saved for the TPU-edt undelete-words command."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (let ((beg (point)))
+    (tpu-forward-to-word num)
+    (setq tpu-last-deleted-words
+          (buffer-substring beg (point)))
+    (delete-region beg (point))))
+
+(defun tpu-delete-previous-word (num)
+  "Delete one or specified number of words before point.
+They are saved for the TPU-edt undelete-words command."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (let ((beg (point)))
+    (tpu-backward-to-word num)
+    (setq tpu-last-deleted-words
+          (buffer-substring (point) beg))
+    (delete-region beg (point))))
+
+(defun tpu-delete-current-char (num)
+  "Delete one or specified number of characters after point.  The last
+character deleted is saved for the TPU-edt undelete-char command."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (while (and (> num 0) (not (eobp)))
+    (setq tpu-last-deleted-char (char-after (point)))
+    (cond (overwrite-mode
+	   (picture-clear-column 1)
+	   (forward-char 1))
+	  (t
+	   (delete-char 1)))
+    (setq num (1- num))))
+
+
+;;;
+;;;  Undelete / Paste
+;;;
+(defun tpu-paste (num)
+  "Insert the last region or rectangle of killed text.
+With argument reinserts the text that many times."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (while (> num 0)
+    (cond (tpu-rectangular-p
+	   (let ((beg (point)))
+	     (save-excursion
+	       (picture-yank-rectangle (not overwrite-mode))
+	       (message ""))
+	     (goto-char beg)))
+	  (t
+	   (insert tpu-last-deleted-region)))
+    (setq num (1- num))))
+
+(defun tpu-undelete-lines (num)
+  "Insert lines deleted by last TPU-edt line-deletion command.
+With argument reinserts lines that many times."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (let ((beg (point)))
+    (while (> num 0)
+      (insert tpu-last-deleted-lines)
+      (setq num (1- num)))
+    (goto-char beg)))
+
+(defun tpu-undelete-words (num)
+  "Insert words deleted by last TPU-edt word-deletion command.
+With argument reinserts words that many times."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (let ((beg (point)))
+    (while (> num 0)
+      (insert tpu-last-deleted-words)
+      (setq num (1- num)))
+    (goto-char beg)))
+
+(defun tpu-undelete-char (num)
+  "Insert character deleted by last TPU-edt character-deletion command.
+With argument reinserts the character that many times."
+  (interactive "p")
+  (setq zmacs-region-stays t)
+  (while (> num 0)
+    (if overwrite-mode (prog1 (forward-char -1) (delete-char 1)))
+    (insert tpu-last-deleted-char)
+    (forward-char -1)
+    (setq num (1- num))))
+
+
+;;;
+;;;  Replace and Substitute
+;;;
+(defun tpu-replace nil
+  "Replace the selected region with the contents of the cut buffer."
+  (interactive)
+  (cond ((tpu-mark)
+	 (let ((beg (region-beginning)) (end (region-end)))
+	   (setq tpu-last-replaced-text (buffer-substring beg end))
+	   (delete-region beg end)
+	   (insert tpu-last-deleted-region)
+	   (tpu-unselect t)))
+	((tpu-check-match)
+	 (let ((beg (tpu-match-beginning)) (end (tpu-match-end)))
+	   (setq tpu-last-replaced-text (buffer-substring beg end))
+	   (replace-match tpu-last-deleted-region
+			  (not case-replace) (not tpu-regexp-p))
+	   (tpu-unset-match)))
+	(t
+	 (error "No selection active."))))
+
+(defun tpu-substitute (num)
+  "Replace the selected region with the contents of the cut buffer, and
+repeat most recent search.  A numeric argument serves as a repeat count.
+A negative argument means replace all occurrences of the search string."
+  (interactive "p")
+  (cond ((or (tpu-mark) (tpu-check-match))
+	 (while (and (not (= num 0)) (or (tpu-mark) (tpu-check-match)))
+	   (let ((beg (point)))
+	     (tpu-replace)
+	     (if tpu-searching-forward (forward-char -1) (goto-char beg))
+	     (if (= num 1) (tpu-search-internal tpu-search-last-string)
+	       (tpu-search-internal-core tpu-search-last-string)))
+	   (setq num (1- num))))
+	(t
+	 (error "No selection active."))))
+
+(defun tpu-lm-replace (from to)
+  "Interactively search for OLD-string and substitute NEW-string."
+  (interactive (list (tpu-regexp-prompt "Old String: ")
+		     (tpu-regexp-prompt "New String: ")))
+
+  (let ((doit t) (strings 0))
+
+    ;; Can't replace null strings
+    (if (string= "" from) (error "No string to replace."))
+
+    ;; Find the first occurrence
+    (tpu-set-search)
+    (tpu-search-internal from t)
+
+    ;; Loop on replace question - yes, no, all, last, or quit.
+    (while doit
+      (if (not (tpu-check-match)) (setq doit nil)
+	(progn (message "Replace? Type Yes, No, All, Last, or Quit: ")
+	       (let ((ans (read-char)))
+
+		 (cond ((or (= ans ?y) (= ans ?Y) (= ans ?\r) (= ans ?\ ))
+			(let ((beg (point)))
+			  (replace-match to (not case-replace) (not tpu-regexp-p))
+			  (setq strings (1+ strings))
+			  (if tpu-searching-forward (forward-char -1) (goto-char beg)))
+			(tpu-search-internal from t))
+
+		       ((or (= ans ?n) (= ans ?N) (= ans ?\C-?))
+			(tpu-search-internal from t))
+
+		       ((or (= ans ?a) (= ans ?A))
+			(save-excursion
+			  (let ((beg (point)))
+			    (replace-match to (not case-replace) (not tpu-regexp-p))
+			    (setq strings (1+ strings))
+			    (if tpu-searching-forward (forward-char -1) (goto-char beg)))
+			  (tpu-search-internal-core from t)
+			  (while (tpu-check-match)
+			    (let ((beg (point)))
+			      (replace-match to (not case-replace) (not tpu-regexp-p))
+			      (setq strings (1+ strings))
+			      (if tpu-searching-forward (forward-char -1) (goto-char beg)))
+			    (tpu-search-internal-core from t)))
+			(setq doit nil))
+
+		       ((or (= ans ?l) (= ans ?L))
+			(let ((beg (point)))
+			  (replace-match to (not case-replace) (not tpu-regexp-p))
+			  (setq strings (1+ strings))
+			  (if tpu-searching-forward (forward-char -1) (goto-char beg)))
+			(setq doit nil))
+
+		       ((or (= ans ?q) (= ans ?Q))
+			(setq doit nil)))))))
+
+    (message "Replaced %s occurrence%s." strings
+	     (if (not (= 1 strings)) "s" ""))))
+
+(defun tpu-emacs-replace (&optional dont-ask)
+  "A TPU-edt interface to the emacs replace functions.  If TPU-edt is
+currently in regular expression mode, the emacs regular expression
+replace functions are used.  If an argument is supplied, replacements
+are performed without asking.  Only works in forward direction."
+  (interactive "P")
+  (cond (dont-ask
+	 (setq current-prefix-arg nil)
+	 (call-interactively
+	  (if tpu-regexp-p 'replace-regexp 'replace-string)))
+	(t
+	 (call-interactively
+	  (if tpu-regexp-p 'query-replace-regexp 'query-replace)))))
+
+(defun tpu-add-at-bol (text)
+  "Add text to the beginning of each line in a region,
+or each line in the entire buffer if no region is selected."
+  (interactive
+   (list (tpu-string-prompt "String to add: " 'tpu-add-at-bol-hist)))
+  (setq zmacs-region-stays t)
+  (if (string= "" text) (error "No string specified."))
+  (cond ((tpu-mark)
+	 (save-excursion
+	   (if (> (point) (tpu-mark)) (exchange-point-and-mark))
+	   (while (and (< (point) (tpu-mark)) (re-search-forward "^" (tpu-mark) t))
+	     (if (< (point) (tpu-mark)) (replace-match text))))
+	 (tpu-unselect t))
+	(t
+	 (save-excursion
+	   (goto-char (point-min))
+	   (while (and (re-search-forward "^" nil t) (not (eobp)))
+	     (replace-match text))))))
+
+(defun tpu-add-at-eol (text)
+  "Add text to the end of each line in a region,
+or each line of the entire buffer if no region is selected."
+  (interactive
+   (list (tpu-string-prompt "String to add: " 'tpu-add-at-eol-hist)))
+  (setq zmacs-region-stays t)
+  (if (string= "" text) (error "No string specified."))
+  (cond ((tpu-mark)
+	 (save-excursion
+	   (if (> (point) (tpu-mark)) (exchange-point-and-mark))
+	   (while (< (point) (tpu-mark))
+	     (end-of-line)
+	     (if (<= (point) (tpu-mark)) (insert text))
+	     (forward-line)))
+	 (tpu-unselect t))
+	(t
+	 (save-excursion
+	   (goto-char (point-min))
+	   (while (not (eobp))
+	     (end-of-line) (insert text) (forward-line))))))
+
+(defun tpu-trim-line-ends nil
+  "Removes trailing whitespace from every line in the buffer."
+  (interactive)
+  (setq zmacs-region-stays t)